public class RotatedTextPresentationImpl
extends ReportItemPresentationBase
{
private RotatedTextItem textItem;
public void setModelObject( ExtendedItemHandle modelHandle )
{
try {
textItem = (RotatedTextItem) modelHandle.getReportItem();
}
catch ( ExtendedElementException e )
{
e.printStackTrace( );
}
}
public int getOutputType( )
{
return OUTPUT_AS_IMAGE;
}
public Object onRowSets( IRowSet[] rowSets )
throws BirtException
{
if ( textItem == null )
{
return null;
}
int angle = textItem.getRotationAngle( );
String text = textItem.getText( );
BufferedImage rotatedImage =
SwingGraphicsUtil.createRotatedTextImage( text, angle,
new Font( "Default", 0, 12 ) ); //$NON-NLS-1$
ByteArrayInputStream bis = null;
try
{
ImageIO.setUseCache( false );
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream ios =
ImageIO.createImageOutputStream( baos );
ImageIO.write( rotatedImage, "png", ios ); //$NON-NLS-1$
ios.flush( );
ios.close( );
bis = new ByteArrayInputStream( baos.toByteArray( ) );
}
catch ( IOException e )
{
e.printStackTrace( );
}
return bis;
}
}
public class SwingGraphicsUtil
{
public static BufferedImage createRotatedTextImage(
String text, int angle, Font ft )
{
Graphics2D g2d = null;
try {
if ( text == null || text.trim( ).length( ) == 0 )
{
return null;
}
BufferedImage stringImage = new BufferedImage( 1, 1,
BufferedImage.TYPE_INT_ARGB );
g2d = (Graphics2D) stringImage.getGraphics( );
g2d.setFont( ft );
FontMetrics fm = g2d.getFontMetrics( );
Rectangle2D bounds = fm.getStringBounds( text, g2d );
TextLayout tl = new TextLayout( text, ft,
g2d.getFontRenderContext( ) );
g2d.dispose( );
g2d = null;
return createRotatedImage( tl, (int) bounds.getWidth( ),
(int) bounds.getHeight( ), angle );
}
catch ( Exception e )
{
e.printStackTrace( );
if ( g2d != null )
{
g2d.dispose( );
}
}
return null;
}
private static BufferedImage createRotatedImage( Object src,
int width, int height, int angle )
{
angle = angle % 360;
if ( angle < 0 )
{
angle += 360;
}
if ( angle == 0 )
{
return renderRotatedObject( src, 0, width, height, 0, 0);
}
else if ( angle == 90 )
{
return renderRotatedObject( src, -Math.PI / 2, height,
width, -width, 0 );
}
else if ( angle == 180 )
{
return renderRotatedObject( src, Math.PI, width, height,
-width, -height );
}
else if ( angle == 270 )
{
return renderRotatedObject( src, Math.PI / 2, height,
width, 0, -height );
}
else if ( angle > 0 && angle < 90 )
{
double angleInRadians = ( ( -angle * Math.PI ) / 180.0 );
double cosTheta = Math.abs( Math.cos( angleInRadians ) );
double sineTheta = Math.abs( Math.sin( angleInRadians ));
int dW = (int) ( width * cosTheta + height * sineTheta );
int dH = (int) ( width * sineTheta + height * cosTheta );
return renderRotatedObject( src, angleInRadians, dW, dH,
-width * sineTheta * sineTheta,
width * sineTheta * cosTheta );
}
else if ( angle > 90 && angle < 180 )
{
double angleInRadians = ( ( -angle * Math.PI ) / 180.0 );
double cosTheta = Math.abs( Math.cos( angleInRadians ) );
double sineTheta = Math.abs( Math.sin( angleInRadians ));
int dW = (int) ( width * cosTheta + height * sineTheta );
int dH = (int) ( width * sineTheta + height * cosTheta );
return renderRotatedObject( src, angleInRadians, dW, dH,
-( width + height * sineTheta * cosTheta ),
-height / 2 );
}
else if ( angle > 180 && angle < 270 )
{
double angleInRadians = ( ( -angle * Math.PI ) / 180.0 );
double cosTheta = Math.abs( Math.cos( angleInRadians ) );
double sineTheta = Math.abs( Math.sin( angleInRadians ));
int dW = (int) ( width * cosTheta + height * sineTheta );
int dH = (int) ( width * sineTheta + height * cosTheta );
return renderRotatedObject( src, angleInRadians, dW, dH,
-( width * cosTheta * cosTheta ),
-( height + width * cosTheta * sineTheta ) );
}
else if ( angle > 270 && angle < 360 )
{
double angleInRadians = ( ( -angle * Math.PI ) / 180.0 );
double cosTheta = Math.abs( Math.cos( angleInRadians ) );
double sineTheta = Math.abs( Math.sin( angleInRadians ));
int dW = (int) ( width * cosTheta + height * sineTheta );
int dH = (int) ( width * sineTheta + height * cosTheta );
return renderRotatedObject( src, angleInRadians, dW, dH,
( height * cosTheta * sineTheta ),
-( height * sineTheta * sineTheta ) );
}
return renderRotatedObject( src, 0, width, height, 0, 0 );
}
private static BufferedImage renderRotatedObject( Object src,
double angle, int width, int height, double tx, double ty )
{
BufferedImage dest = new BufferedImage( width, height,
BufferedImage.TYPE_INT_ARGB );
Graphics2D g2d = (Graphics2D) dest.getGraphics( );
g2d.setColor( Color.black );
g2d.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON );
g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON );
AffineTransform at = AffineTransform.getRotateInstance(
angle );
at.translate( tx, ty );
g2d.setTransform( at );
if ( src instanceof TextLayout )
{
TextLayout tl = (TextLayout) src;
tl.draw( g2d, 0, tl.getAscent( ) );
}
else if ( src instanceof Image )
{
g2d.drawImage( (Image) src, 0, 0, null );
}
g2d.dispose( );
return dest;
}
}