Quantcast
Channel: makemachine » Cinder
Viewing all articles
Browse latest Browse all 7

Pixel Bounds of Text in Cinder OpenGL Texture

$
0
0

Rendering text with Cinder is a pretty simple process. The TextLayout class allows you to easily display text as a Texture on the GPU. However, fonts are strange creatures and tend to vary greatly in their metrics. The project I’m working on right now needs to use the actual area of each character rendered. Harvesting such data proved to be a little tricky and led me to hand roll this functionality.

In the screenshot above the white rectangle is drawn to the area of the texture returned from the TextLayout.render() method. The bluish rectangle is drawn based on the area generated from evaluating the alpha channel of the the texture and hence the true pixel bounds.

Above is another example demonstrating the same. Note the difference in the amount of space in the white rectangles around the text in the two images. As in the first image the blue rectangle tightly fits around the actual pixels of the text. Below is the guts of the function that creates the pixel bounds.

font = Font( loadResource( RES_FONT_COPY ), 118 );
layout.setFont( font );
layout.setColor( ColorA( 1.0f, 1.0f, 1.0f, 1.0f ) );
layout.addLine( "Pixel Bounds" );
	
surface = layout.render( true, false );
texture = Texture( surface );

Area bounds = texture.getCleanBounds();
Surface::Iter iter = surface.getIter( bounds );

pixelBounds.x1 = bounds.x2;
pixelBounds.y1 = bounds.y2;
pixelBounds.y2 = bounds.y1;
pixelBounds.x2 = bounds.x1;

while( iter.line() ) 
{
	while( iter.pixel() ) 
	{
		int x = 0;
		int y = 0;
		
		if (iter.a() > 0 ) 
		{
			x = iter.getPos().x;
			y = iter.getPos().y;
			
			pixelBounds.x1 = std::min( x, pixelBounds.x1 );
			pixelBounds.y1 = std::min( y, pixelBounds.y1 );
			pixelBounds.x2 = std::max( x, pixelBounds.x2 );
			pixelBounds.y2 = std::max( y, pixelBounds.y2 );
		}
	}
}

In the project I’m working, the pixel bounds for each character are required. The algorithm also works for this.

I have yet to test this function with a Texture containing anything other than text, but it seems as though it should work.

Get the full example code on GitHub


Viewing all articles
Browse latest Browse all 7

Trending Articles