#442 SVG BaseURI issue fix

This commit is contained in:
Harald Kuhr
2018-10-11 21:38:10 +02:00
parent 62538c3db9
commit cc5af0134c
4 changed files with 311 additions and 35 deletions
@@ -110,24 +110,25 @@ public class SVGImageReader extends ImageReaderBase {
public BufferedImage read(int pIndex, ImageReadParam pParam) throws IOException {
checkBounds(pIndex);
String baseURI = null;
if (pParam instanceof SVGReadParam) {
SVGReadParam svgParam = (SVGReadParam) pParam;
// Set IIOParams as hints
// Get the base URI
// This must be done before converting the params to hints
String baseURI = svgParam.getBaseURI();
rasterizer.transcoderInput.setURI(baseURI);
// Set ImageReadParams as hints
// Note: The cast to Map invokes a different method that preserves
// unset defaults, DO NOT REMOVE!
rasterizer.setTranscodingHints((Map) paramsToHints(svgParam));
// Get the base URI (not a hint)
baseURI = svgParam.getBaseURI();
}
Dimension size;
if (pParam != null && (size = pParam.getSourceRenderSize()) != null) {
// Use size...
Dimension size = null;
if (pParam != null) {
size = pParam.getSourceRenderSize();
}
else {
if (size == null) {
size = new Dimension(getWidth(pIndex), getHeight(pIndex));
}
@@ -137,7 +138,6 @@ public class SVGImageReader extends ImageReaderBase {
try {
processImageStarted(pIndex);
rasterizer.transcoderInput.setURI(baseURI);
BufferedImage image = rasterizer.getImage();
Graphics2D g = destination.createGraphics();
@@ -155,10 +155,16 @@ public class SVGImageReader extends ImageReaderBase {
return destination;
}
catch (TranscoderException e) {
throw new IIOException(e.getMessage(), e);
Throwable cause = unwrapException(e);
throw new IIOException(cause.getMessage(), cause);
}
}
private static Throwable unwrapException(TranscoderException ex) {
// The TranscoderException is generally useless...
return ex.getException() != null ? ex.getException() : ex;
}
private TranscodingHints paramsToHints(SVGReadParam pParam) throws IOException {
TranscodingHints hints = new TranscodingHints();
// Note: We must allow generic ImageReadParams, so converting to
@@ -174,8 +180,8 @@ public class SVGImageReader extends ImageReaderBase {
}
if (size != null) {
hints.put(ImageTranscoder.KEY_WIDTH, new Float(size.getWidth()));
hints.put(ImageTranscoder.KEY_HEIGHT, new Float(size.getHeight()));
hints.put(ImageTranscoder.KEY_WIDTH, (float) size.getWidth());
hints.put(ImageTranscoder.KEY_HEIGHT, (float) size.getHeight());
}
// Set area of interest
@@ -185,16 +191,16 @@ public class SVGImageReader extends ImageReaderBase {
// Avoid that the batik transcoder scales the AOI up to original image size
if (size == null) {
hints.put(ImageTranscoder.KEY_WIDTH, new Float(region.getWidth()));
hints.put(ImageTranscoder.KEY_HEIGHT, new Float(region.getHeight()));
hints.put(ImageTranscoder.KEY_WIDTH, (float) region.getWidth());
hints.put(ImageTranscoder.KEY_HEIGHT, (float) region.getHeight());
}
else {
// Need to resize here...
double xScale = size.getWidth() / origSize.getWidth();
double yScale = size.getHeight() / origSize.getHeight();
hints.put(ImageTranscoder.KEY_WIDTH, new Float(region.getWidth() * xScale));
hints.put(ImageTranscoder.KEY_HEIGHT, new Float(region.getHeight() * yScale));
hints.put(ImageTranscoder.KEY_WIDTH, (float) (region.getWidth() * xScale));
hints.put(ImageTranscoder.KEY_HEIGHT, (float) (region.getHeight() * yScale));
}
}
else if (size != null) {
@@ -219,7 +225,7 @@ public class SVGImageReader extends ImageReaderBase {
return null;
}
public ImageReadParam getDefaultReadParam() {
public SVGReadParam getDefaultReadParam() {
return new SVGReadParam();
}
@@ -255,7 +261,7 @@ public class SVGImageReader extends ImageReaderBase {
*/
private class Rasterizer extends SVGAbstractTranscoder /*ImageTranscoder*/ {
BufferedImage image = null;
private BufferedImage image;
private TranscoderInput transcoderInput;
private float defaultWidth;
private float defaultHeight;
@@ -266,17 +272,19 @@ public class SVGImageReader extends ImageReaderBase {
private TranscoderException exception;
private BridgeContext context;
public BufferedImage createImage(final int width, final int height) {
return ImageUtil.createTransparent(width, height);//, BufferedImage.TYPE_INT_ARGB);
private BufferedImage createImage(final int width, final int height) {
return ImageUtil.createTransparent(width, height); // BufferedImage.TYPE_INT_ARGB
}
// This is cheating... We don't fully transcode after all
protected void transcode(Document document, final String uri, final TranscoderOutput output) throws TranscoderException {
// Sets up root, curTxf & curAoi
// ----
if ((document != null) && !(document.getImplementation() instanceof SVGDOMImplementation)) {
DOMImplementation impl = (DOMImplementation) hints.get(KEY_DOM_IMPLEMENTATION);
document = DOMUtilities.deepCloneDocument(document, impl);
if (document != null) {
if (!(document.getImplementation() instanceof SVGDOMImplementation)) {
DOMImplementation impl = (DOMImplementation) hints.get(KEY_DOM_IMPLEMENTATION);
document = DOMUtilities.deepCloneDocument(document, impl);
}
if (uri != null) {
try {
@@ -346,8 +354,8 @@ public class SVGImageReader extends ImageReaderBase {
processReadAborted();
return null;
}
processImageProgress(10f);
processImageProgress(10f);
// Hacky workaround below...
if (gvtRoot == null) {
@@ -369,6 +377,7 @@ public class SVGImageReader extends ImageReaderBase {
}
ctx = context;
// /Hacky
if (abortRequested()) {
processReadAborted();
return null;
@@ -489,11 +498,9 @@ public class SVGImageReader extends ImageReaderBase {
// now we are sure that the aoi is the image size
Shape raoi = new Rectangle2D.Float(0, 0, width, height);
// Warning: the renderer's AOI must be in user space
renderer.repaint(curTxf.createInverse().
createTransformedShape(raoi));
renderer.repaint(curTxf.createInverse().createTransformedShape(raoi));
// NOTE: repaint above cause nullpointer exception with fonts..???
BufferedImage rend = renderer.getOffScreen();
renderer = null; // We're done with it...
@@ -558,18 +565,40 @@ public class SVGImageReader extends ImageReaderBase {
return image;
}
protected int getDefaultWidth() throws TranscoderException {
int getDefaultWidth() throws TranscoderException {
init();
return (int) (defaultWidth + 0.5);
return (int) Math.ceil(defaultWidth);
}
protected int getDefaultHeight() throws TranscoderException {
int getDefaultHeight() throws TranscoderException {
init();
return (int) (defaultHeight + 0.5);
return (int) Math.ceil(defaultHeight);
}
public void setInput(final TranscoderInput pInput) {
void setInput(final TranscoderInput pInput) {
transcoderInput = pInput;
}
@Override
protected UserAgent createUserAgent() {
return new SVGImageReaderUserAgent();
}
private class SVGImageReaderUserAgent extends SVGAbstractTranscoderUserAgent {
@Override
public void displayError(Exception e) {
displayError(e.getMessage());
}
@Override
public void displayError(String message) {
displayMessage(message);
}
@Override
public void displayMessage(String message) {
processWarningOccurred(message.replaceAll("[\\r\\n]+", " "));
}
}
}
}