if ( Pixel::RGBA8888 == pixelFormat )
{
// Whether the given glyph is a color one.
- const bool isColorGlyph = Pixel::BGRA8888 == data.glyphBitmap.format;
+ const bool isColorGlyph = data.glyphBitmap.isColorEmoji || data.glyphBitmap.isColorBitmap;
+ const uint32_t glyphPixelSize = Pixel::GetBytesPerPixel( data.glyphBitmap.format );
+ const uint32_t alphaIndex = glyphPixelSize - 1u;
+ const bool swapChannelsBR = Pixel::BGRA8888 == data.glyphBitmap.format;
// Pointer to the color glyph if there is one.
const uint32_t* const colorGlyphBuffer = isColorGlyph ? reinterpret_cast<uint32_t*>( data.glyphBitmap.buffer ) : NULL;
// Initial vertical offset.
const int yOffset = data.verticalOffset + position->y;
+ uint32_t* bitmapBuffer = reinterpret_cast< uint32_t* >( data.bitmapBuffer.GetBuffer() );
+
// Traverse the pixels of the glyph line per line.
for( int lineIndex = 0, glyphHeight = static_cast<int>( data.glyphBitmap.height ); lineIndex < glyphHeight; ++lineIndex )
{
continue;
}
- uint32_t* bitmapBuffer = reinterpret_cast< uint32_t* >( data.bitmapBuffer.GetBuffer() );
-
if( isColorGlyph )
{
- // Retrieves the color from the color glyph. The format is BGRA8888.
+ // Retrieves the color from the color glyph.
uint32_t packedColorGlyph = *( colorGlyphBuffer + glyphBufferOffset + index );
uint8_t* packedColorGlyphBuffer = reinterpret_cast<uint8_t*>( &packedColorGlyph );
}
else
{
- uint8_t colorAlpha = static_cast<uint8_t>( color->a * static_cast<float>( *( packedColorGlyphBuffer + 3u ) ) );
+ const uint8_t colorAlpha = static_cast<uint8_t>( color->a * static_cast<float>( *( packedColorGlyphBuffer + 3u ) ) );
*( packedColorGlyphBuffer + 3u ) = colorAlpha;
if( Typesetter::STYLE_SHADOW == style )
}
else
{
- std::swap( *packedColorGlyphBuffer, *( packedColorGlyphBuffer + 2u ) ); // Swap B and R.
+ if( swapChannelsBR )
+ {
+ std::swap( *packedColorGlyphBuffer, *( packedColorGlyphBuffer + 2u ) ); // Swap B and R.
+ }
*( packedColorGlyphBuffer + 2u ) = ( *( packedColorGlyphBuffer + 2u ) * colorAlpha / 255 );
*( packedColorGlyphBuffer + 1u ) = ( *( packedColorGlyphBuffer + 1u ) * colorAlpha / 255 );
*packedColorGlyphBuffer = ( *( packedColorGlyphBuffer ) * colorAlpha / 255 );
+
+ if( data.glyphBitmap.isColorBitmap )
+ {
+ *( packedColorGlyphBuffer + 2u ) = static_cast<uint8_t>( *( packedColorGlyphBuffer + 2u ) * color->b );
+ *( packedColorGlyphBuffer + 1u ) = static_cast<uint8_t>( *( packedColorGlyphBuffer + 1u ) * color->g );
+ *packedColorGlyphBuffer = static_cast<uint8_t>( *packedColorGlyphBuffer * color->r );
+ }
}
}
uint8_t* packedColorBuffer = reinterpret_cast<uint8_t*>( &packedColor );
// Update the alpha channel.
- const uint8_t alpha = *( data.glyphBitmap.buffer + glyphBufferOffset + index );
+ const uint8_t alpha = *( data.glyphBitmap.buffer + glyphPixelSize * ( glyphBufferOffset + index ) + alphaIndex );
// Copy non-transparent pixels only
if ( alpha > 0u )
else
{
// Whether the given glyph is a color one.
- const bool isColorGlyph = Pixel::BGRA8888 == data.glyphBitmap.format;
+ const bool isColorGlyph = data.glyphBitmap.isColorEmoji || data.glyphBitmap.isColorBitmap;
+ const uint32_t glyphPixelSize = Pixel::GetBytesPerPixel( data.glyphBitmap.format );
+ const uint32_t alphaIndex = glyphPixelSize - 1u;
// Initial vertical offset.
const int yOffset = data.verticalOffset + position->y;
+ uint8_t* bitmapBuffer = reinterpret_cast< uint8_t* >( data.bitmapBuffer.GetBuffer() );
+
// Traverse the pixels of the glyph line per line.
for( int lineIndex = 0, glyphHeight = static_cast<int>( data.glyphBitmap.height ); lineIndex < glyphHeight; ++lineIndex )
{
continue;
}
- uint8_t* bitmapBuffer = reinterpret_cast< uint8_t* >( data.bitmapBuffer.GetBuffer() );
-
if ( !isColorGlyph )
{
// Update the alpha channel.
- const uint8_t alpha = *( data.glyphBitmap.buffer + glyphBufferOffset + index );
+ const uint8_t alpha = *( data.glyphBitmap.buffer + glyphPixelSize * ( glyphBufferOffset + index ) + alphaIndex );
// Copy non-transparent pixels only
if ( alpha > 0u )
// overwrite a previous bigger alpha with a smaller alpha (in order to avoid
// semi-transparent gaps between joint glyphs with overlapped pixels, which could
// happen, for example, in the RTL text when we copy glyphs from right to left).
- *( bitmapBuffer + verticalOffset + xOffsetIndex ) = std::max( currentAlpha, alpha );
+ currentAlpha = std::max( currentAlpha, alpha );
}
}
}
// Don't render outline for other styles
outlineWidth = 0.0f;
}
+
if( style != Typesetter::STYLE_UNDERLINE )
{
fontClient.CreateBitmap( glyphInfo->fontId,
static_cast<int>( outlineWidth ) );
}
-
// Sets the glyph's bitmap into the bitmap of the whole text.
if( NULL != glyphData.glyphBitmap.buffer )
{
+ if ( style == Typesetter::STYLE_OUTLINE )
+ {
+ // Set the position offset for the current glyph
+ glyphData.horizontalOffset -= glyphData.glyphBitmap.outlineOffsetX;
+ glyphData.verticalOffset -= glyphData.glyphBitmap.outlineOffsetY;
+ }
+
+ // Set the buffer of the glyph's bitmap into the final bitmap's buffer
TypesetGlyph( glyphData,
position,
&color,
style,
pixelFormat);
+
+ if ( style == Typesetter::STYLE_OUTLINE )
+ {
+ // Reset the position offset for the next glyph
+ glyphData.horizontalOffset += glyphData.glyphBitmap.outlineOffsetX;
+ glyphData.verticalOffset += glyphData.glyphBitmap.outlineOffsetY;
+ }
+
// delete the glyphBitmap.buffer as it is now copied into glyphData.bitmapBuffer
delete []glyphData.glyphBitmap.buffer;
glyphData.glyphBitmap.buffer = NULL;