net.sf.jasperreports.renderers.BatikRenderer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jasperreports Show documentation
Show all versions of jasperreports Show documentation
Free Java Reporting Library
/*
* JasperReports - Free Java Reporting Library.
* Copyright (C) 2001 - 2019 TIBCO Software Inc. All rights reserved.
* http://www.jaspersoft.com
*
* Unless you have purchased a commercial license agreement from Jaspersoft,
* the following license terms apply:
*
* This program is part of JasperReports.
*
* JasperReports is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JasperReports 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JasperReports. If not, see .
*/
package net.sf.jasperreports.renderers;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Dimension2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.List;
import org.apache.batik.anim.dom.SAXSVGDocumentFactory;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.bridge.UserAgentAdapter;
import org.apache.batik.bridge.ViewBox;
import org.apache.batik.dom.svg.SVGDocumentFactory;
import org.apache.batik.ext.awt.image.GraphicsUtil;
import org.apache.batik.gvt.GraphicsNode;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGPreserveAspectRatio;
import net.sf.jasperreports.engine.JRConstants;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRPrintImageAreaHyperlink;
import net.sf.jasperreports.engine.JRRuntimeException;
import net.sf.jasperreports.engine.JasperReportsContext;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.repo.RepositoryUtil;
/**
* SVG renderer implementation based on Batik.
*
* @author Lucian Chirita ([email protected])
* @deprecated Replaced by {@link ResourceRenderer} and {@link DataRenderable}.
*/
public class BatikRenderer extends net.sf.jasperreports.engine.JRAbstractSvgRenderer implements net.sf.jasperreports.engine.ImageMapRenderable, DataRenderable, RenderToImageAwareRenderable
{
private static final long serialVersionUID = JRConstants.SERIAL_VERSION_UID;
/**
* @deprecated Replaced by {@link BatikUserAgent}.
*/
protected static class JRUserAgent extends UserAgentAdapter
{
@Override
public float getPixelUnitToMillimeter()
{
// JR works at 72dpi
return 0.35277777777777777777777777777778f;
}
}
private String svgText;
private byte[] svgData;
private String svgDataLocation;
private List areaHyperlinks;
private int minDPI;
private boolean antiAlias;
private transient GraphicsNode rootNode;
private transient Dimension2D documentSize;
protected BatikRenderer(List areaHyperlinks)
{
this.areaHyperlinks = areaHyperlinks;
}
/**
* Creates a SVG renderer.
*
* @param svgText the SVG text
* @param areaHyperlinks a list of {@link JRPrintImageAreaHyperlink area hyperlinks}
*/
public BatikRenderer(String svgText, List areaHyperlinks)
{
this.svgText = svgText;
this.areaHyperlinks = areaHyperlinks;
}
/**
* Creates a SVG renderer.
*
* @param svgData the SVG (binary) data
* @param areaHyperlinks a list of {@link JRPrintImageAreaHyperlink area hyperlinks}
*/
public BatikRenderer(byte[] svgData, List areaHyperlinks)
{
this.svgData = svgData;
this.areaHyperlinks = areaHyperlinks;
}
@Override
public void render(JasperReportsContext jasperReportsContext, Graphics2D grx, Rectangle2D rectangle) throws JRException
{
ensureSvg(jasperReportsContext);
AffineTransform transform = ViewBox.getPreserveAspectRatioTransform(
new float[]{0, 0, (float) documentSize.getWidth(), (float) documentSize.getHeight()},
SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE, true,
(float) rectangle.getWidth(), (float) rectangle.getHeight());
Graphics2D graphics = (Graphics2D) grx.create();
try
{
graphics.translate(rectangle.getX(), rectangle.getY());
graphics.transform(transform);
// CompositeGraphicsNode not thread safe
synchronized (rootNode)
{
rootNode.paint(graphics);
}
}
finally
{
graphics.dispose();
}
}
@Override
public Dimension2D getDimension(JasperReportsContext jasperReportsContext)
{
try
{
ensureSvg(jasperReportsContext);
return documentSize;
}
catch (JRException e)
{
throw new JRRuntimeException(e);
}
}
@Override
public byte[] getData(JasperReportsContext jasperReportsContext) throws JRException
{
ensureData(jasperReportsContext);
if (svgText != null)
{
try
{
return svgText.getBytes("UTF-8");
}
catch (UnsupportedEncodingException e)
{
throw new JRRuntimeException(e);
}
}
else
{
return svgData;
}
}
protected synchronized void ensureData(JasperReportsContext jasperReportsContext) throws JRException
{
if (svgText == null
&& svgData == null && svgDataLocation != null)
{
svgData = RepositoryUtil.getInstance(jasperReportsContext).getBytesFromLocation(svgDataLocation);
}
}
protected synchronized void ensureSvg(JasperReportsContext jasperReportsContext) throws JRException
{
if (rootNode != null)
{
// already loaded
return;
}
ensureData(jasperReportsContext);
try
{
UserAgent userAgent = new BatikUserAgent(jasperReportsContext);
SVGDocumentFactory documentFactory =
new SAXSVGDocumentFactory(userAgent.getXMLParserClassName(), true);
documentFactory.setValidating(userAgent.isXMLParserValidating());
SVGDocument document;
if (svgText != null)
{
document = documentFactory.createSVGDocument(null,
new StringReader(svgText));
}
else
{
document = documentFactory.createSVGDocument(null,
new ByteArrayInputStream(svgData));
}
BridgeContext ctx = new BridgeContext(userAgent);
ctx.setDynamic(true);
GVTBuilder builder = new GVTBuilder();
rootNode = builder.build(ctx, document);
documentSize = ctx.getDocumentSize();
}
catch (IOException e)
{
throw new JRRuntimeException(e);
}
}
/**
* @deprecated To be removed.
*/
@Override
public List renderWithHyperlinks(Graphics2D grx, Rectangle2D rectangle) throws JRException
{
render(grx, rectangle);
return areaHyperlinks;
}
@Override
public List getImageAreaHyperlinks(Rectangle2D renderingArea) throws JRException
{
return areaHyperlinks;
}
@Override
public boolean hasImageAreaHyperlinks()
{
return areaHyperlinks != null && !areaHyperlinks.isEmpty();
}
@Override
public Graphics2D createGraphics(BufferedImage bi)
{
Graphics2D graphics = GraphicsUtil.createGraphics(bi);
if (antiAlias)
{
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//FIXME use JPG instead of PNG for smaller size?
}
return graphics;
}
/**
* @deprecated Replaced by {@link ResourceRenderer}.
*/
protected void setSvgDataLocation(String svgDataLocation)
{
this.svgDataLocation = svgDataLocation;
}
/**
* Creates a SVG renderer from binary data.
*
* @param svgData the SVG (binary) data
* @return a SVG renderer
*/
public static BatikRenderer getInstance(byte[] svgData)
{
return new BatikRenderer(svgData, null);
}
/**
* Creates a SVG renderer from a data stream.
*
*
* Note: the data stream is exhausted, but not closed.
*
*
* @param svgDataStream the SVG binary data stream
* @return a SVG renderer
* @throws JRException
*/
public static BatikRenderer getInstance(InputStream svgDataStream) throws JRException
{
byte[] data = JRLoader.loadBytes(svgDataStream);
return new BatikRenderer(data, null);
}
/**
* Creates a SVG renderer from a file.
*
* @param svgFile the SVG file to read
* @return a SVG renderer
* @throws JRException
*/
public static BatikRenderer getInstance(File svgFile) throws JRException
{
byte[] data = JRLoader.loadBytes(svgFile);
return new BatikRenderer(data, null);
}
/**
* Creates a SVG renderer from a {@link URL}.
*
* @param svgURL the SVG URL
* @return a SVG renderer
* @throws JRException
*/
public static BatikRenderer getInstance(URL svgURL) throws JRException
{
byte[] data = JRLoader.loadBytes(svgURL);
return new BatikRenderer(data, null);
}
/**
* Creates a SVG renderer from SVG text.
*
* @param svgText the SVG text
* @return a SVG renderer
* @throws JRException
*/
public static BatikRenderer getInstanceFromText(String svgText) throws JRException
{
return new BatikRenderer(svgText, null);
}
/**
* Creates a SVG renderer by loading data from a generic location.
*
* @param location the location
* @return a SVG renderer
* @throws JRException
* @see RepositoryUtil#getBytesFromLocation(String)
*/
public static BatikRenderer getInstanceFromLocation(JasperReportsContext jasperReportsContext, String location) throws JRException
{
byte[] data = RepositoryUtil.getInstance(jasperReportsContext).getBytesFromLocation(location);
return new BatikRenderer(data, null);
}
/**
* Creates a lazily loaded SVG renderer for a location.
*
*
* The returned renderer loads the SVG data lazily, i.e. only when the data
* is actually required (which is at the first
* {@link #render(JasperReportsContext, Graphics2D, Rectangle2D)}}.
*
*
* @param location the SVG location
* @throws JRException
* @deprecated Replaced by {@link ResourceRenderer}.
*/
public static BatikRenderer getLocationInstance(String location) throws JRException
{
BatikRenderer renderer = new BatikRenderer(null);
renderer.setSvgDataLocation(location);
return renderer;
}
@Override
public int getImageDataDPI(JasperReportsContext jasperReportsContext)
{
int dpi = super.getImageDataDPI(jasperReportsContext);
if (minDPI > 0 && dpi < minDPI)
{
dpi = minDPI;
}
return dpi;
}
public int getMinDPI()
{
return minDPI;
}
public void setMinDPI(int minDPI)
{
this.minDPI = minDPI;
}
public boolean isAntiAlias()
{
return antiAlias;
}
public void setAntiAlias(boolean antiAlias)
{
this.antiAlias = antiAlias;
}
}