/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2015 by Pentaho : http://www.pentaho.com
*
*******************************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
package org.pentaho.di.core;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.util.Map;
import java.util.TreeMap;
/**
* Universal image storage for Swing processing. It contains SVG or bitmap image depends on file and settings.
*/
public abstract class SwingUniversalImage {
private Map<String, BufferedImage> cache = new TreeMap<String, BufferedImage>();
public abstract boolean isBitmap();
/**
* Just scale for area's size.
*/
protected abstract void renderSimple( BufferedImage area );
/**
* Render with scale, at specified position, with possible rotation.
*/
protected abstract void render( Graphics2D gc, int centerX, int centerY, int width, int height, double angleRadians );
/**
* Get scaled image.
*/
public synchronized BufferedImage getAsBitmapForSize( int width, int height ) {
String key = width + "x" + height;
BufferedImage result = cache.get( key );
if ( result == null ) {
result = createBitmap( width, height );
renderSimple( result );
cache.put( key, result );
}
return result;
}
/**
* Draw rotated image on double canvas size. It required against lost corners on rotate.
*/
public synchronized BufferedImage getAsBitmapForSize( int width, int height, double angleRadians ) {
int angleDegree = (int) Math.round( Math.toDegrees( angleRadians ) );
while ( angleDegree < 0 ) {
angleDegree += 360;
}
angleDegree %= 360;
angleRadians = Math.toRadians( angleDegree );
String key = width + "x" + height + "/" + Integer.toString( angleDegree );
BufferedImage result = cache.get( key );
if ( result == null ) {
result = createDoubleBitmap( width, height );
Graphics2D gc = createGraphics( result );
render( gc, result.getWidth() / 2, result.getHeight() / 2, width, height, angleRadians );
gc.dispose();
cache.put( key, result );
}
return result;
}
public synchronized void drawToGraphics( Graphics2D gc, int locationX, int locationY, int width, int height ) {
render( gc, locationX + width / 2, locationY + height / 2, width, height, 0 );
}
public synchronized void drawToGraphics( Graphics2D gc, int centerX, int centerY, int width, int height,
double angleRadians ) {
render( gc, centerX, centerY, width, height, angleRadians );
}
/**
* Create bitmap with specified size and full colorspace.
*/
public static BufferedImage createBitmap( int width, int height ) {
return new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB );
}
/**
* Create bitmap with double of specified size and full colorspace. Used for rotated images.
*/
public static BufferedImage createDoubleBitmap( int width, int height ) {
int sz = Math.max( width, height ) * 2;
return new BufferedImage( sz, sz, BufferedImage.TYPE_INT_ARGB );
}
/**
* Create Graphics2D for specified bitmap with rendering hints.
*/
public static Graphics2D createGraphics( BufferedImage area ) {
Graphics2D gc = (Graphics2D) area.getGraphics();
gc.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
gc.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
gc.setRenderingHint( RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY );
gc.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC );
gc.setRenderingHint( RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE );
return gc;
}
}