/*! ****************************************************************************** * * 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.image.BufferedImage; import java.util.Map; import java.util.TreeMap; import org.eclipse.swt.graphics.Device; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.PaletteData; import org.eclipse.swt.graphics.RGB; /** * Universal image storage for SWT processing. It contains SVG or bitmap image depends on file and settings. */ public abstract class SwtUniversalImage { private Map<String, Image> cache = new TreeMap<String, Image>(); @Deprecated protected abstract Image renderSimple( Device device ); protected abstract Image renderSimple( Device device, int width, int height ); protected abstract Image renderRotated( Device device, int width, int height, double angleRadians ); public synchronized void dispose() { if ( cache == null ) { return; } for ( Image img : cache.values() ) { if ( !img.isDisposed() ) { img.dispose(); } } cache = null; } private void checkDisposed() { if ( cache == null ) { throw new RuntimeException( "Already disposed" ); } } /** * @deprecated Use getAsBitmapForSize() instead. */ @Deprecated public synchronized Image getAsBitmap( Device device ) { checkDisposed(); Image result = cache.get( "" ); if ( result == null ) { result = renderSimple( device ); cache.put( "", result ); } return result; } /** * Method getAsBitmapForSize(..., angle) can't be called, because it returns bigger picture. */ public synchronized Image getAsBitmapForSize( Device device, int width, int height ) { checkDisposed(); String key = width + "x" + height; Image result = cache.get( key ); if ( result == null ) { result = renderSimple( device, width, height ); cache.put( key, result ); } return result; } /** * Draw rotated image on double canvas size. It required against lost corners on rotate. */ public synchronized Image getAsBitmapForSize( Device device, int width, int height, double angleRadians ) { checkDisposed(); int angleDegree = (int) Math.round( Math.toDegrees( angleRadians ) ); while ( angleDegree < 0 ) { angleDegree += 360; } angleDegree %= 360; angleRadians = Math.toRadians( angleDegree ); String key = width + "x" + height + "/" + angleDegree; Image result = cache.get( key ); if ( result == null ) { result = renderRotated( device, width, height, angleRadians ); cache.put( key, result ); } return result; } /** * Converts BufferedImage to SWT/Image with alpha channel. */ protected Image swing2swt( Device device, BufferedImage img ) { PaletteData palette = new PaletteData( 0xFF0000, 0xFF00, 0xFF ); ImageData data = new ImageData( img.getWidth(), img.getHeight(), 32, palette ); for ( int y = 0; y < data.height; y++ ) { for ( int x = 0; x < data.width; x++ ) { int rgba = img.getRGB( x, y ); int rgb = palette.getPixel( new RGB( ( rgba >> 16 ) & 0xFF, ( rgba >> 8 ) & 0xFF, rgba & 0xFF ) ); int a = ( rgba >> 24 ) & 0xFF; data.setPixel( x, y, rgb ); data.setAlpha( x, y, a ); } } return new Image( device, data ); } }