2 * Copyright (c) 2019 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>
26 #if defined(DEBUG_ENABLED)
27 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_RENDERING");
30 } // unnamed namespace
41 AtlasGlyphManager::AtlasGlyphManager()
43 mAtlasManager = Dali::Toolkit::AtlasManager::New();
44 mSampler = Sampler::New();
45 mSampler.SetFilterMode( FilterMode::LINEAR, FilterMode::LINEAR );
48 void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
49 const Toolkit::AtlasGlyphManager::GlyphStyle& style,
50 const PixelData& bitmap,
51 Dali::Toolkit::AtlasManager::AtlasSlot& slot )
53 DALI_LOG_INFO( gLogFilter, Debug::General, "Added glyph, font: %d index: %d\n", glyph.fontId, glyph.index );
55 // If glyph added to an existing or new atlas then a new glyph record is required.
56 // Check if an existing atlas will fit the image, create a new one if required.
57 if ( mAtlasManager.Add( bitmap, slot ) )
59 // A new atlas was created so set the texture set details for the atlas
60 Dali::Texture atlas = mAtlasManager.GetAtlasContainer( slot.mAtlasId );
61 TextureSet textureSet = TextureSet::New();
62 textureSet.SetTexture( 0u, atlas );
63 textureSet.SetSampler( 0u, mSampler);
64 mAtlasManager.SetTextures( slot.mAtlasId, textureSet );
67 GlyphRecordEntry record;
68 record.mIndex = glyph.index;
69 record.mImageId = slot.mImageId;
71 record.mOutlineWidth = style.outline;
72 record.isItalic = style.isItalic;
73 record.isBold = style.isBold;
75 // Have glyph records been created for this fontId ?
76 bool foundGlyph = false;
77 for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
78 fontGlyphRecordIt != mFontGlyphRecords.end(); ++fontGlyphRecordIt )
80 if ( fontGlyphRecordIt->mFontId == glyph.fontId )
82 fontGlyphRecordIt->mGlyphRecords.PushBack( record );
90 // We need to add a new font entry
91 FontGlyphRecord fontGlyphRecord;
92 fontGlyphRecord.mFontId = glyph.fontId;
93 fontGlyphRecord.mGlyphRecords.PushBack( record );
94 mFontGlyphRecords.push_back( fontGlyphRecord );
98 void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
99 const Vector2& position,
100 Toolkit::AtlasManager::Mesh2D& mesh )
102 // Generate mesh data and tell Atlas Manager not to handle reference counting ( we'll do it )
103 mAtlasManager.GenerateMeshData( imageId, position, mesh, false );
106 bool AtlasGlyphManager::IsCached( Text::FontId fontId,
107 Text::GlyphIndex index,
108 const Toolkit::AtlasGlyphManager::GlyphStyle& style,
109 Dali::Toolkit::AtlasManager::AtlasSlot& slot )
111 for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
112 fontGlyphRecordIt != mFontGlyphRecords.end();
113 ++fontGlyphRecordIt )
115 if ( fontGlyphRecordIt->mFontId == fontId )
117 for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
118 glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
121 if ( ( glyphRecordIt->mIndex == index ) &&
122 ( glyphRecordIt->mOutlineWidth == style.outline ) &&
123 ( glyphRecordIt->isItalic == style.isItalic ) &&
124 ( glyphRecordIt->isBold == style.isBold ) )
126 slot.mImageId = glyphRecordIt->mImageId;
127 slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId );
137 Vector2 AtlasGlyphManager::GetAtlasSize( uint32_t atlasId )
139 Toolkit::AtlasManager::AtlasSize size = mAtlasManager.GetAtlasSize( atlasId );
140 return Vector2( static_cast< float >( size.mWidth ), static_cast< float >( size.mHeight ) );
143 void AtlasGlyphManager::SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight )
145 Toolkit::AtlasManager::AtlasSize size;
147 size.mHeight = height;
148 size.mBlockWidth = blockWidth;
149 size.mBlockHeight = blockHeight;
150 mAtlasManager.SetNewAtlasSize( size );
153 Pixel::Format AtlasGlyphManager::GetPixelFormat( uint32_t atlasId )
155 return mAtlasManager.GetPixelFormat( atlasId );
158 const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
160 std::ostringstream verboseMetrics;
162 mMetrics.mGlyphCount = 0u;
163 for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
164 fontGlyphRecordIt != mFontGlyphRecords.end();
165 ++fontGlyphRecordIt )
167 mMetrics.mGlyphCount += fontGlyphRecordIt->mGlyphRecords.Size();
169 verboseMetrics << "[FontId " << fontGlyphRecordIt->mFontId << " Glyph ";
170 for ( Vector< GlyphRecordEntry >::Iterator glyphRecordEntryIt = fontGlyphRecordIt->mGlyphRecords.Begin();
171 glyphRecordEntryIt != fontGlyphRecordIt->mGlyphRecords.End();
172 ++glyphRecordEntryIt )
174 verboseMetrics << glyphRecordEntryIt->mIndex << "(" << glyphRecordEntryIt->mCount << ") ";
176 verboseMetrics << "] ";
178 mMetrics.mVerboseGlyphCounts = verboseMetrics.str();
180 mAtlasManager.GetMetrics( mMetrics.mAtlasMetrics );
185 void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, const Toolkit::AtlasGlyphManager::GlyphStyle& style, int32_t delta )
189 DALI_LOG_INFO( gLogFilter, Debug::General, "AdjustReferenceCount %d, font: %d index: %d\n", delta, fontId, index );
191 for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
192 fontGlyphRecordIt != mFontGlyphRecords.end();
193 ++fontGlyphRecordIt )
195 if ( fontGlyphRecordIt->mFontId == fontId )
197 for ( Vector< GlyphRecordEntry >::Iterator glyphRecordIt = fontGlyphRecordIt->mGlyphRecords.Begin();
198 glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
201 if ( ( glyphRecordIt->mIndex == index ) &&
202 ( glyphRecordIt->mOutlineWidth == style.outline ) &&
203 ( glyphRecordIt->isItalic == style.isItalic ) &&
204 ( glyphRecordIt->isBold == style.isBold ) )
206 glyphRecordIt->mCount += delta;
207 DALI_ASSERT_DEBUG( glyphRecordIt->mCount >= 0 && "Glyph ref-count should not be negative" );
209 if ( !glyphRecordIt->mCount )
211 mAtlasManager.Remove( glyphRecordIt->mImageId );
212 fontGlyphRecordIt->mGlyphRecords.Remove( glyphRecordIt );
220 // Should not arrive here
221 DALI_ASSERT_DEBUG( false && "Failed to adjust ref-count" );
225 TextureSet AtlasGlyphManager::GetTextures( uint32_t atlasId ) const
227 return mAtlasManager.GetTextures( atlasId );
230 AtlasGlyphManager::~AtlasGlyphManager()
232 // mAtlasManager handle is automatically released here
235 } // namespace Internal
237 } // namespace Toolkit