2 * Copyright (c) 2021 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/integration-api/debug.h>
25 #if defined(DEBUG_ENABLED)
26 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_RENDERING");
29 } // unnamed namespace
37 AtlasGlyphManager::AtlasGlyphManager()
39 mAtlasManager = Dali::Toolkit::AtlasManager::New();
40 mSampler = Sampler::New();
41 mSampler.SetFilterMode(FilterMode::LINEAR, FilterMode::LINEAR);
44 void AtlasGlyphManager::Add(const Text::GlyphInfo& glyph,
45 const Toolkit::AtlasGlyphManager::GlyphStyle& style,
46 const PixelData& bitmap,
47 Dali::Toolkit::AtlasManager::AtlasSlot& slot)
49 DALI_LOG_INFO(gLogFilter, Debug::General, "Added glyph, font: %d index: %d\n", glyph.fontId, glyph.index);
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))
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);
63 GlyphRecordEntry record;
64 record.mIndex = glyph.index;
65 record.mImageId = slot.mImageId;
67 record.mOutlineWidth = style.outline;
68 record.isItalic = style.isItalic;
69 record.isBold = style.isBold;
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();
77 if(fontGlyphRecordIt->mFontId == glyph.fontId)
79 fontGlyphRecordIt->mGlyphRecords.PushBack(record);
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);
95 void AtlasGlyphManager::GenerateMeshData(uint32_t imageId,
96 const Vector2& position,
97 Toolkit::AtlasManager::Mesh2D& mesh)
99 // Generate mesh data and tell Atlas Manager not to handle reference counting ( we'll do it )
100 mAtlasManager.GenerateMeshData(imageId, position, mesh, false);
103 bool AtlasGlyphManager::IsCached(Text::FontId fontId,
104 Text::GlyphIndex index,
105 const Toolkit::AtlasGlyphManager::GlyphStyle& style,
106 Dali::Toolkit::AtlasManager::AtlasSlot& slot)
108 for(std::vector<FontGlyphRecord>::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
109 fontGlyphRecordIt != mFontGlyphRecords.end();
112 if(fontGlyphRecordIt->mFontId == fontId)
114 for(Vector<GlyphRecordEntry>::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
115 glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
118 if((glyphRecordIt->mIndex == index) &&
119 (glyphRecordIt->mOutlineWidth == style.outline) &&
120 (glyphRecordIt->isItalic == style.isItalic) &&
121 (glyphRecordIt->isBold == style.isBold))
123 slot.mImageId = glyphRecordIt->mImageId;
124 slot.mAtlasId = mAtlasManager.GetAtlas(slot.mImageId);
134 Vector2 AtlasGlyphManager::GetAtlasSize(uint32_t atlasId)
136 Toolkit::AtlasManager::AtlasSize size = mAtlasManager.GetAtlasSize(atlasId);
137 return Vector2(static_cast<float>(size.mWidth), static_cast<float>(size.mHeight));
140 void AtlasGlyphManager::SetNewAtlasSize(uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight)
142 Toolkit::AtlasManager::AtlasSize size;
144 size.mHeight = height;
145 size.mBlockWidth = blockWidth;
146 size.mBlockHeight = blockHeight;
147 mAtlasManager.SetNewAtlasSize(size);
150 Pixel::Format AtlasGlyphManager::GetPixelFormat(uint32_t atlasId)
152 return mAtlasManager.GetPixelFormat(atlasId);
155 const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
157 std::ostringstream verboseMetrics;
159 mMetrics.mGlyphCount = 0u;
160 for(std::vector<FontGlyphRecord>::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
161 fontGlyphRecordIt != mFontGlyphRecords.end();
164 mMetrics.mGlyphCount += fontGlyphRecordIt->mGlyphRecords.Size();
166 verboseMetrics << "[FontId " << fontGlyphRecordIt->mFontId << " Glyph ";
167 for(Vector<GlyphRecordEntry>::Iterator glyphRecordEntryIt = fontGlyphRecordIt->mGlyphRecords.Begin();
168 glyphRecordEntryIt != fontGlyphRecordIt->mGlyphRecords.End();
169 ++glyphRecordEntryIt)
171 verboseMetrics << glyphRecordEntryIt->mIndex << "(" << glyphRecordEntryIt->mCount << ") ";
173 verboseMetrics << "] ";
175 mMetrics.mVerboseGlyphCounts = verboseMetrics.str();
177 mAtlasManager.GetMetrics(mMetrics.mAtlasMetrics);
182 void AtlasGlyphManager::AdjustReferenceCount(Text::FontId fontId, Text::GlyphIndex index, const Toolkit::AtlasGlyphManager::GlyphStyle& style, int32_t delta)
186 DALI_LOG_INFO(gLogFilter, Debug::General, "AdjustReferenceCount %d, font: %d index: %d\n", delta, fontId, index);
188 for(std::vector<FontGlyphRecord>::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
189 fontGlyphRecordIt != mFontGlyphRecords.end();
192 if(fontGlyphRecordIt->mFontId == fontId)
194 for(Vector<GlyphRecordEntry>::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
195 glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
198 if((glyphRecordIt->mIndex == index) &&
199 (glyphRecordIt->mOutlineWidth == style.outline) &&
200 (glyphRecordIt->isItalic == style.isItalic) &&
201 (glyphRecordIt->isBold == style.isBold))
203 glyphRecordIt->mCount += delta;
204 DALI_ASSERT_DEBUG(glyphRecordIt->mCount >= 0 && "Glyph ref-count should not be negative");
206 if(!glyphRecordIt->mCount)
208 mAtlasManager.Remove(glyphRecordIt->mImageId);
209 fontGlyphRecordIt->mGlyphRecords.Remove(glyphRecordIt);
217 // Should not arrive here
218 DALI_ASSERT_DEBUG(false && "Failed to adjust ref-count");
222 TextureSet AtlasGlyphManager::GetTextures(uint32_t atlasId) const
224 return mAtlasManager.GetTextures(atlasId);
227 AtlasGlyphManager::~AtlasGlyphManager()
229 // mAtlasManager handle is automatically released here
232 } // namespace Internal
234 } // namespace Toolkit