/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2001 - 2013 Object Refinery Ltd, Pentaho Corporation and Contributors.. All rights reserved. */ package org.pentaho.reporting.engine.classic.core; import java.awt.Image; import java.io.IOException; import java.io.Serializable; import java.net.URL; import org.pentaho.reporting.libraries.base.util.ObjectUtilities; import org.pentaho.reporting.libraries.base.util.WaitingImageObserver; import org.pentaho.reporting.libraries.resourceloader.Resource; import org.pentaho.reporting.libraries.resourceloader.ResourceException; import org.pentaho.reporting.libraries.resourceloader.ResourceKey; /** * An DefaultImageReference encapsulates the source of an image together with a <code>java.awt.Image</code>. The source * is used to create a higher resolution version if needed. The source file/URL may also be inlined into the output * target, to create better results. * <p/> * This implementation provides a reasonable default implementation to encapsualte local AWT-images into reports. * <p/> * The given image might specify a fixed scale factor for the given image. The scaling will be applied before any layout * computations will be performed. * * @author Thomas Morgner */ public class DefaultImageReference implements Serializable, URLImageContainer, LocalImageContainer { /** * A unique identifier for long term persistance. */ private static final long serialVersionUID = 3223926147102983309L; /** * The image. */ private Image image; /** * The image URL. */ private URL url; /** * The width of the (unscaled) image. */ private int width; /** * The height of the (unscaled) image. */ private int height; /** * The scale factor. */ private float scaleX = 1.0f; /** * The scale factor. */ private float scaleY = 1.0f; private ResourceKey resourceKey; /** * Creates a new ImageReference without an assigned URL for the Image. This image reference will not be loadable and * cannot be used to embedd the original rawdata of the image into the generated content. * * @param img * the image for this reference. * @throws NullPointerException * if the image is null. * @throws java.io.IOException * if an IOError occured while loading the image. */ public DefaultImageReference( final Image img ) throws IOException { if ( img == null ) { throw new NullPointerException(); } this.image = img; final WaitingImageObserver obs = new WaitingImageObserver( image ); obs.waitImageLoaded(); if ( obs.isError() ) { throw new IOException( "Failed to load the image. ImageObserver signaled an error." ); } this.width = image.getWidth( null ); this.height = image.getHeight( null ); } public DefaultImageReference( final Resource imageResource ) throws ResourceException { if ( imageResource == null ) { throw new NullPointerException(); } final Object o = imageResource.getResource(); if ( o instanceof Image == false ) { throw new ResourceException( "ImageResource does not contain a java.awt.Image object." ); } final ResourceKey resKey = imageResource.getSource(); final Object identifier = resKey.getIdentifier(); if ( identifier instanceof URL ) { this.url = (URL) identifier; } this.resourceKey = resKey; this.image = (Image) o; final WaitingImageObserver obs = new WaitingImageObserver( image ); obs.waitImageLoaded(); if ( obs.isError() ) { throw new ResourceException( "Failed to load the image. ImageObserver signaled an error." ); } this.width = image.getWidth( null ); this.height = image.getHeight( null ); } /** * Creates a new image reference without assigning either an Image or an URL. This DefaultImageReference will act as * place holder to reserve space during the layouting, no content will be generated. * * @param w * the width of the unscaled image. * @param h * the height of the unscaled image. */ public DefaultImageReference( final int w, final int h ) { this.width = w; this.height = h; } /** * Copies the contents of the given DefaultImageReference. * * @param parent * the parent. */ public DefaultImageReference( final DefaultImageReference parent ) { if ( parent == null ) { throw new NullPointerException( "The given parent must not be null." ); } this.width = parent.width; this.height = parent.height; this.image = parent.image; this.url = parent.url; this.resourceKey = parent.resourceKey; } /** * Returns the original image if available. * * @return The current image instance, or null, if no image has been assigned. */ public Image getImage() { return image; } /** * Returns the source URL for the image. * * @return The URL from where the image has been loaded, or null, if the source URL is not known. */ public URL getSourceURL() { return url; } /** * Returns the a string version of the source URL. If no URL has been assigned, this method will return null. * * @return a String representing the assigned URL. */ public String getSourceURLString() { if ( url == null ) { return null; } return url.toExternalForm(); } /** * Returns a String representing this object. Useful for debugging. * * @return The string. */ public String toString() { final StringBuffer buf = new StringBuffer( 100 ); buf.append( "ImageReference={ URL=" ); buf.append( getSourceURL() ); buf.append( ", key=" ); buf.append( getResourceKey() ); buf.append( ", image=" ); buf.append( getImage() ); buf.append( ", width=" ); buf.append( getImageWidth() ); buf.append( ", height=" ); buf.append( getImageHeight() ); buf.append( ", scaleX=" ); buf.append( getScaleX() ); buf.append( ", scaleY=" ); buf.append( getScaleY() ); buf.append( '}' ); return buf.toString(); } public ResourceKey getResourceKey() { return resourceKey; } /** * Checks for equality. * * @param obj * the object to test. * @return true if the specified object is equal to this one. */ public boolean equals( final Object obj ) { if ( obj == null ) { return false; } if ( obj instanceof DefaultImageReference == false ) { return false; } final DefaultImageReference ref = (DefaultImageReference) obj; if ( ObjectUtilities.equal( String.valueOf( url ), String.valueOf( ref.url ) ) == false ) { return false; } if ( width != ref.width ) { return false; } if ( height != ref.height ) { return false; } if ( scaleX != ref.scaleX ) { return false; } if ( scaleY != ref.scaleY ) { return false; } return true; } /** * Compute a hashcode for this imageReference. * * @return the hashcode */ public int hashCode() { int result = width; result = 29 * result + height; result = 29 * result + Float.floatToIntBits( scaleX ); result = 29 * result + Float.floatToIntBits( scaleY ); result = 29 * result + ( image != null ? image.hashCode() : 0 ); result = 29 * result + ( url != null ? url.toString().hashCode() : 0 ); return result; } /** * Clones this Element. * * @return a clone of this element. * @throws CloneNotSupportedException * this should never be thrown. */ public Object clone() throws CloneNotSupportedException { return super.clone(); } /** * Returns the (unscaled) image width. * * @return the image width. */ public int getImageWidth() { return width; } /** * Returns the (unscaled) image height. * * @return the image height. */ public int getImageHeight() { return height; } /** * Checks whether this image reference is loadable. A default image reference is loadable, if a valid URL has been * set. * * @return true, if it is loadable, false otherwise. */ public boolean isLoadable() { return getResourceKey() != null; } /** * Returns the identity information. This instance returns the URL of the image, if any. * * @return the image identifier. */ public Object getIdentity() { if ( url == null ) { return null; } return String.valueOf( url ); } /** * Returns the name of this image reference. If an URL has been set, this will return the URL of the image, else null * is returned. * * @return the name. */ public String getName() { if ( url != null ) { return url.toExternalForm(); } return null; } /** * Checks whether this image has a assigned identity. Two identities should be equal, if the image contents are equal. * * @return true, if that image contains contains identity information, false otherwise. */ public boolean isIdentifiable() { return url != null; } /** * Returns a predefined scaling factor. That scaling will be applied before any layout specific scaling is done. * * @return the scale factor. */ public float getScaleX() { return scaleX; } /** * Returns a predefined scaling factor. That scaling will be applied before any layout specific scaling is done. * * @return the scale factor. */ public float getScaleY() { return scaleY; } /** * Defines a predefined scaling factor. That scaling will be applied before any layout specific scaling is done. * <p/> * If your image has a higher resolution than 72dpi, this factor should be a value lower than 1 (the image will be * scaled down). * * @param sx * the scale factor. * @param sy * the scale factor. */ public void setScale( final float sx, final float sy ) { this.scaleX = sx; this.scaleY = sy; } }