+ const bool glyphNotCached = !mGlyphManager.IsCached(glyph.fontId, glyph.index, style, slot); // Check FontGlyphRecord vector for entry with glyph index and fontId
+
+ DALI_LOG_INFO(gLogFilter, Debug::Verbose, "AddGlyphs fontID[%u] glyphIndex[%u] [%s]\n", glyph.fontId, glyph.index, (glyphNotCached) ? "not cached" : "cached");
+
+ if(glyphNotCached)
+ {
+ MaxBlockSize& blockSize = mBlockSizes[0u];
+
+ if(lastFontId != glyph.fontId)
+ {
+ uint32_t index = 0u;
+ // Looks through all stored block sizes until finds the one which mataches required glyph font it. Ensures new atlas block size will match existing for same font id.
+ // CalculateBlocksSize() above ensures a block size entry exists.
+ for(std::vector<MaxBlockSize>::const_iterator it = mBlockSizes.begin(),
+ endIt = mBlockSizes.end();
+ it != endIt;
+ ++it, ++index)
+ {
+ const MaxBlockSize& blockSizeEntry = *it;
+ if(blockSizeEntry.mFontId == glyph.fontId)
+ {
+ blockSize = mBlockSizes[index];
+ }
+ }
+ }
+
+ // Create a new image for the glyph
+ PixelData bitmap;
+
+ // Whether the glyph is an outline.
+ const bool isOutline = 0u != style.outline;
+
+ // Whether the current glyph is a color one.
+ const bool isColorGlyph = mFontClient.IsColorGlyph(glyph.fontId, glyph.index);
+
+ if(!isOutline || (isOutline && !isColorGlyph))
+ {
+ // Retrieve the emoji's bitmap.
+ TextAbstraction::FontClient::GlyphBufferData glyphBufferData;
+ glyphBufferData.width = isColorGlyph ? glyph.width : 0; // Desired width and height.
+ glyphBufferData.height = isColorGlyph ? glyph.height : 0;
+
+ mFontClient.CreateBitmap(glyph.fontId,
+ glyph.index,
+ glyph.isItalicRequired,
+ glyph.isBoldRequired,
+ glyphBufferData,
+ style.outline);
+
+ // Create the pixel data.
+ bitmap = PixelData::New(glyphBufferData.buffer,
+ glyphBufferData.width * glyphBufferData.height * GetBytesPerPixel(glyphBufferData.format),
+ glyphBufferData.width,
+ glyphBufferData.height,
+ glyphBufferData.format,
+ PixelData::DELETE_ARRAY);
+
+ if(bitmap)
+ {
+ // Ensure that the next image will fit into the current block size
+ if(bitmap.GetWidth() > blockSize.mNeededBlockWidth)
+ {
+ blockSize.mNeededBlockWidth = bitmap.GetWidth();
+ }
+
+ if(bitmap.GetHeight() > blockSize.mNeededBlockHeight)
+ {
+ blockSize.mNeededBlockHeight = bitmap.GetHeight();
+ }
+
+ // If CheckAtlas in AtlasManager::Add can't fit the bitmap in the current atlas it will create a new atlas
+
+ // Setting the block size and size of new atlas does not mean a new one will be created. An existing atlas may still surffice.
+ uint32_t default_width = DEFAULT_ATLAS_WIDTH;
+ uint32_t default_height = DEFAULT_ATLAS_HEIGHT;
+
+ while (
+ (blockSize.mNeededBlockWidth >= (default_width - (DOUBLE_PIXEL_PADDING + 1u)) ||
+ blockSize.mNeededBlockHeight >= (default_height - (DOUBLE_PIXEL_PADDING + 1u)))
+ &&
+ (default_width < MAX_ATLAS_WIDTH &&
+ default_height < MAX_ATLAS_HEIGHT))
+ {
+ default_width <<= 1u;
+ default_height <<= 1u;
+ }
+ mGlyphManager.SetNewAtlasSize(default_width,
+ default_height,
+ blockSize.mNeededBlockWidth,
+ blockSize.mNeededBlockHeight);
+
+ // Locate a new slot for our glyph
+ mGlyphManager.Add(glyph, style, bitmap, slot); // slot will be 0 is glyph not added
+ }
+ }
+ }
+ else
+ {
+ // We have 2+ copies of the same glyph
+ mGlyphManager.AdjustReferenceCount(glyph.fontId, glyph.index, style, 1); //increment
+ }
+ }
+
+ void GenerateMesh(const GlyphInfo& glyph,
+ const Vector2& position,
+ const Vector4& color,
+ uint16_t outline,
+ AtlasManager::AtlasSlot& slot,
+ bool underlineGlyph,
+ float currentUnderlinePosition,
+ float currentUnderlineThickness,
+ std::vector<MeshRecord>& meshContainer,
+ Vector<TextCacheEntry>& newTextCache,
+ Vector<Extent>& extents)
+ {
+ // Generate mesh data for this quad, plugging in our supplied position
+ AtlasManager::Mesh2D newMesh;
+ mGlyphManager.GenerateMeshData(slot.mImageId, position, newMesh);
+