+ // Generate the image buffers of the text for each different style first,
+ // then combine all of them together as one final image buffer. We try to
+ // do all of these in CPU only, so that once the final texture is generated,
+ // no calculation is needed in GPU during each frame.
+
+ const unsigned int bufferWidth = static_cast<unsigned int>( size.width );
+ const unsigned int bufferHeight = static_cast<unsigned int>( size.height );
+
+ const unsigned int bufferSizeInt = bufferWidth * bufferHeight;
+ const unsigned int bufferSizeChar = 4u * bufferSizeInt;
+
+ Length numberOfGlyphs = mModel->GetNumberOfGlyphs();
+
+ Devel::PixelBuffer imageBuffer;
+
+ if( RENDER_MASK == behaviour )
+ {
+ // Generate the image buffer as an alpha mask for color glyphs.
+ imageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_MASK, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs - 1 );
+ }
+ else if( RENDER_NO_TEXT == behaviour )
+ {
+ // Generate an empty image buffer so that it can been combined with the image buffers for styles
+ imageBuffer = Devel::PixelBuffer::New( bufferWidth, bufferHeight, Pixel::RGBA8888 );
+ memset( imageBuffer.GetBuffer(), 0u, bufferSizeChar );
+ }
+ else
+ {
+ // Generate the image buffer for the text with no style.
+ imageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_NONE, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs -1 );
+ }
+
+ if ( ( RENDER_NO_STYLES != behaviour ) && ( RENDER_MASK != behaviour ) )
+ {
+ // @todo. Support shadow and underline for partial text later on.
+
+ // Generate the shadow if enabled
+ const Vector2& shadowOffset = mModel->GetShadowOffset();
+ if ( fabsf( shadowOffset.x ) > Math::MACHINE_EPSILON_1 || fabsf( shadowOffset.y ) > Math::MACHINE_EPSILON_1 )
+ {
+ // Create the image buffer for shadow
+ Devel::PixelBuffer shadowImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_SHADOW, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs - 1 );
+
+ // Combine the two buffers
+ imageBuffer = CombineImageBuffer( imageBuffer, shadowImageBuffer, bufferWidth, bufferHeight );
+ }
+
+ // Generate the underline if enabled
+ const bool underlineEnabled = mModel->IsUnderlineEnabled();
+ if ( underlineEnabled )
+ {
+ // Create the image buffer for underline
+ Devel::PixelBuffer underlineImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_UNDERLINE, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs - 1 );
+
+ // Combine the two buffers
+ imageBuffer = CombineImageBuffer( imageBuffer, underlineImageBuffer, bufferWidth, bufferHeight );
+ }
+ }
+
+ // Create the final PixelData for the combined image buffer
+ PixelData pixelData = Devel::PixelBuffer::Convert( imageBuffer );
+
+ return pixelData;
+}
+
+Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth, const unsigned int bufferHeight, Typesetter::Style style, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, int verticalOffset, GlyphIndex fromGlyphIndex, GlyphIndex toGlyphIndex )
+{