com.kitfox.svg.app.beans.SVGIcon Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of svg-salamander Show documentation
Show all versions of svg-salamander Show documentation
A tool for displaying and playing SVG content using the Java2D
The newest version!
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at [email protected]. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on April 21, 2005, 10:45 AM
*/
package com.kitfox.svg.app.beans;
import com.kitfox.svg.SVGCache;
import com.kitfox.svg.SVGDiagram;
import com.kitfox.svg.SVGException;
import com.kitfox.svg.SVGUniverse;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.net.URI;
import javax.swing.ImageIcon;
/**
*
* @author kitfox
*/
public class SVGIcon extends ImageIcon
{
public static final long serialVersionUID = 1;
public static final String PROP_AUTOSIZE = "PROP_AUTOSIZE";
private final PropertyChangeSupport changes = new PropertyChangeSupport(this);
SVGUniverse svgUniverse = SVGCache.getSVGUniverse();
public static final int INTERP_NEAREST_NEIGHBOR = 0;
public static final int INTERP_BILINEAR = 1;
public static final int INTERP_BICUBIC = 2;
private boolean antiAlias;
private int interpolation = INTERP_NEAREST_NEIGHBOR;
private boolean clipToViewbox;
URI svgURI;
// private boolean scaleToFit;
AffineTransform scaleXform = new AffineTransform();
public static final int AUTOSIZE_NONE = 0;
public static final int AUTOSIZE_HORIZ = 1;
public static final int AUTOSIZE_VERT = 2;
public static final int AUTOSIZE_BESTFIT = 3;
public static final int AUTOSIZE_STRETCH = 4;
private int autosize = AUTOSIZE_NONE;
Dimension preferredSize;
/** Creates a new instance of SVGIcon */
public SVGIcon()
{
}
public void addPropertyChangeListener(PropertyChangeListener p)
{
changes.addPropertyChangeListener(p);
}
public void removePropertyChangeListener(PropertyChangeListener p)
{
changes.removePropertyChangeListener(p);
}
@Override
public Image getImage()
{
BufferedImage bi = new BufferedImage(getIconWidth(), getIconHeight(), BufferedImage.TYPE_INT_ARGB);
paintIcon(null, bi.getGraphics(), 0, 0);
return bi;
}
/**
* @return height of this icon
*/
public int getIconHeightIgnoreAutosize()
{
if (preferredSize != null &&
(autosize == AUTOSIZE_VERT || autosize == AUTOSIZE_STRETCH
|| autosize == AUTOSIZE_BESTFIT))
{
return preferredSize.height;
}
SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
if (diagram == null)
{
return 0;
}
return (int)diagram.getHeight();
}
/**
* @return width of this icon
*/
public int getIconWidthIgnoreAutosize()
{
if (preferredSize != null &&
(autosize == AUTOSIZE_HORIZ || autosize == AUTOSIZE_STRETCH
|| autosize == AUTOSIZE_BESTFIT))
{
return preferredSize.width;
}
SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
if (diagram == null)
{
return 0;
}
return (int)diagram.getWidth();
}
private boolean isAutoSizeBestFitUseFixedHeight(final int iconWidthIgnoreAutosize, final int iconHeightIgnoreAutosize,
final SVGDiagram diagram)
{
return iconHeightIgnoreAutosize/diagram.getHeight() < iconWidthIgnoreAutosize/diagram.getWidth();
}
@Override
public int getIconWidth()
{
final int iconWidthIgnoreAutosize = getIconWidthIgnoreAutosize();
final int iconHeightIgnoreAutosize = getIconHeightIgnoreAutosize();
final SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
if (preferredSize != null && (autosize == AUTOSIZE_VERT ||
(autosize == AUTOSIZE_BESTFIT && isAutoSizeBestFitUseFixedHeight(iconWidthIgnoreAutosize, iconHeightIgnoreAutosize, diagram))))
{
final double aspectRatio = diagram.getHeight()/diagram.getWidth();
return (int)(iconHeightIgnoreAutosize / aspectRatio);
}
else
{
return iconWidthIgnoreAutosize;
}
}
@Override
public int getIconHeight()
{
final int iconWidthIgnoreAutosize = getIconWidthIgnoreAutosize();
final int iconHeightIgnoreAutosize = getIconHeightIgnoreAutosize();
final SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
if (preferredSize != null && (autosize == AUTOSIZE_HORIZ ||
(autosize == AUTOSIZE_BESTFIT && !isAutoSizeBestFitUseFixedHeight(iconWidthIgnoreAutosize, iconHeightIgnoreAutosize, diagram))))
{
final double aspectRatio = diagram.getHeight()/diagram.getWidth();
return (int)(iconWidthIgnoreAutosize * aspectRatio);
}
else
{
return iconHeightIgnoreAutosize;
}
}
/**
* Draws the icon to the specified component.
* @param comp - Component to draw icon to. This is ignored by SVGIcon, and can be set to null; only gg is used for drawing the icon
* @param gg - Graphics context to render SVG content to
* @param x - X coordinate to draw icon
* @param y - Y coordinate to draw icon
*/
@Override
public void paintIcon(Component comp, Graphics gg, int x, int y)
{
//Copy graphics object so that
Graphics2D g = (Graphics2D)gg.create();
paintIcon(comp, g, x, y);
g.dispose();
}
private void paintIcon(Component comp, Graphics2D g, int x, int y)
{
Object oldAliasHint = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antiAlias ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF);
Object oldInterpolationHint = g.getRenderingHint(RenderingHints.KEY_INTERPOLATION);
switch (interpolation)
{
case INTERP_NEAREST_NEIGHBOR:
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
break;
case INTERP_BILINEAR:
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
break;
case INTERP_BICUBIC:
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
break;
}
SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
if (diagram == null)
{
return;
}
g.translate(x, y);
diagram.setIgnoringClipHeuristic(!clipToViewbox);
if (clipToViewbox)
{
g.setClip(new Rectangle2D.Float(0, 0, diagram.getWidth(), diagram.getHeight()));
}
if (autosize == AUTOSIZE_NONE)
{
try
{
diagram.render(g);
g.translate(-x, -y);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAliasHint);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
return;
}
final int width = getIconWidthIgnoreAutosize();
final int height = getIconHeightIgnoreAutosize();
// int width = getWidth();
// int height = getHeight();
if (width == 0 || height == 0)
{
return;
}
// if (width == 0 || height == 0)
// {
// //Chances are we're rendering offscreen
// Dimension dim = getSize();
// width = dim.width;
// height = dim.height;
// return;
// }
// g.setClip(0, 0, width, height);
// final Rectangle2D.Double rect = new Rectangle2D.Double();
// diagram.getViewRect(rect);
//
// scaleXform.setToScale(width / rect.width, height / rect.height);
double diaWidth = diagram.getWidth();
double diaHeight = diagram.getHeight();
double scaleW = 1;
double scaleH = 1;
if (autosize == AUTOSIZE_BESTFIT)
{
scaleW = scaleH = (height / diaHeight < width / diaWidth)
? height / diaHeight : width / diaWidth;
}
else if (autosize == AUTOSIZE_HORIZ)
{
scaleW = scaleH = width / diaWidth;
}
else if (autosize == AUTOSIZE_VERT)
{
scaleW = scaleH = height / diaHeight;
}
else if (autosize == AUTOSIZE_STRETCH)
{
scaleW = width / diaWidth;
scaleH = height / diaHeight;
}
scaleXform.setToScale(scaleW, scaleH);
AffineTransform oldXform = g.getTransform();
g.transform(scaleXform);
try
{
diagram.render(g);
}
catch (SVGException e)
{
throw new RuntimeException(e);
}
g.setTransform(oldXform);
g.translate(-x, -y);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAliasHint);
if (oldInterpolationHint != null)
{
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, oldInterpolationHint);
}
}
/**
* @return the universe this icon draws it's SVGDiagrams from
*/
public SVGUniverse getSvgUniverse()
{
return svgUniverse;
}
public void setSvgUniverse(SVGUniverse svgUniverse)
{
SVGUniverse old = this.svgUniverse;
this.svgUniverse = svgUniverse;
changes.firePropertyChange("svgUniverse", old, svgUniverse);
}
/**
* @return the uni of the document being displayed by this icon
*/
public URI getSvgURI()
{
return svgURI;
}
/**
* Loads an SVG document from a URI.
* @param svgURI - URI to load document from
*/
public void setSvgURI(URI svgURI)
{
URI old = this.svgURI;
this.svgURI = svgURI;
SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
if (diagram != null)
{
Dimension size = getPreferredSize();
if (size == null)
{
size = new Dimension((int)diagram.getRoot().getDeviceWidth(), (int)diagram.getRoot().getDeviceHeight());
}
diagram.setDeviceViewport(new Rectangle(0, 0, size.width, size.height));
}
changes.firePropertyChange("svgURI", old, svgURI);
}
/**
* Loads an SVG document from the classpath. This function is equivilant to
* setSvgURI(new URI(getClass().getResource(resourcePath).toString());
* @param resourcePath - resource to load
*/
public void setSvgResourcePath(String resourcePath)
{
URI old = this.svgURI;
try
{
svgURI = new URI(getClass().getResource(resourcePath).toString());
changes.firePropertyChange("svgURI", old, svgURI);
SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
if (diagram != null)
{
diagram.setDeviceViewport(new Rectangle(0, 0, preferredSize.width, preferredSize.height));
}
}
catch (Exception e)
{
svgURI = old;
}
}
/**
* If this SVG document has a viewbox, if scaleToFit is set, will scale the viewbox to match the
* preferred size of this icon
* @deprecated
* @return
*/
public boolean isScaleToFit()
{
return autosize == AUTOSIZE_STRETCH;
}
/**
* @deprecated
*/
public void setScaleToFit(boolean scaleToFit)
{
setAutosize(AUTOSIZE_STRETCH);
// boolean old = this.scaleToFit;
// this.scaleToFit = scaleToFit;
// firePropertyChange("scaleToFit", old, scaleToFit);
}
public Dimension getPreferredSize()
{
if (preferredSize == null)
{
SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
if (diagram != null)
{
//preferredSize = new Dimension((int)diagram.getWidth(), (int)diagram.getHeight());
setPreferredSize(new Dimension((int)diagram.getWidth(), (int)diagram.getHeight()));
}
}
return new Dimension(preferredSize);
}
public void setPreferredSize(Dimension preferredSize)
{
Dimension old = this.preferredSize;
this.preferredSize = preferredSize;
SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
if (diagram != null)
{
diagram.setDeviceViewport(new Rectangle(0, 0, preferredSize.width, preferredSize.height));
}
changes.firePropertyChange("preferredSize", old, preferredSize);
}
/**
* @return true if antiAliasing is turned on.
* @deprecated
*/
public boolean getUseAntiAlias()
{
return getAntiAlias();
}
/**
* @param antiAlias true to use antiAliasing.
* @deprecated
*/
public void setUseAntiAlias(boolean antiAlias)
{
setAntiAlias(antiAlias);
}
/**
* @return true if antiAliasing is turned on.
*/
public boolean getAntiAlias()
{
return antiAlias;
}
/**
* @param antiAlias true to use antiAliasing.
*/
public void setAntiAlias(boolean antiAlias)
{
boolean old = this.antiAlias;
this.antiAlias = antiAlias;
changes.firePropertyChange("antiAlias", old, antiAlias);
}
/**
* @return interpolation used in rescaling images
*/
public int getInterpolation()
{
return interpolation;
}
/**
* @param interpolation Interpolation value used in rescaling images.
* Should be one of
* INTERP_NEAREST_NEIGHBOR - Fastest, one pixel resampling, poor quality
* INTERP_BILINEAR - four pixel resampling
* INTERP_BICUBIC - Slowest, nine pixel resampling, best quality
*/
public void setInterpolation(int interpolation)
{
int old = this.interpolation;
this.interpolation = interpolation;
changes.firePropertyChange("interpolation", old, interpolation);
}
/**
* clipToViewbox will set a clip box equivilant to the SVG's viewbox before
* rendering.
*/
public boolean isClipToViewbox()
{
return clipToViewbox;
}
public void setClipToViewbox(boolean clipToViewbox)
{
this.clipToViewbox = clipToViewbox;
}
/**
* @return the autosize
*/
public int getAutosize()
{
return autosize;
}
/**
* @param autosize the autosize to set
*/
public void setAutosize(int autosize)
{
int oldAutosize = this.autosize;
this.autosize = autosize;
changes.firePropertyChange(PROP_AUTOSIZE, oldAutosize, autosize);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy