Fixed intrinsic size calculation for SVG images when source resolution is not 72 dpi. Fixed calculation of px2mm values in the SVG to G2D converter (used by RTF output). git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/fop-0_95@670551 13f79535-47bb-0310-9956-ffa450edef68tags/fop-0_95
@@ -5,9 +5,9 @@ | |||
* The ASF licenses this file to You 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. | |||
@@ -16,7 +16,7 @@ | |||
*/ | |||
/* $Id$ */ | |||
package org.apache.fop.image.loader.batik; | |||
import java.awt.Dimension; | |||
@@ -48,7 +48,7 @@ import org.apache.fop.svg.SVGUserAgent; | |||
* Note: The target flavor is "generic" Java2D. No Batik-specific bridges are hooked into the | |||
* conversion process. Specialized renderers may want to provide specialized adapters to profit | |||
* from target-format features (for example with PDF or PS). This converter is mainly for formats | |||
* which only support bitmap images or rudimentary Java2D support. | |||
* which only support bitmap images or rudimentary Java2D support. | |||
*/ | |||
public class ImageConverterSVG2G2D extends AbstractImageConverter { | |||
@@ -62,10 +62,10 @@ public class ImageConverterSVG2G2D extends AbstractImageConverter { | |||
} | |||
//Prepare | |||
float pxToMillimeter = (float)UnitConv.mm2in(72); //default: 72dpi | |||
float pxToMillimeter = UnitConv.IN2MM / 72; //default: 72dpi | |||
Number ptm = (Number)hints.get(ImageProcessingHints.SOURCE_RESOLUTION); | |||
if (ptm != null) { | |||
pxToMillimeter = (float)UnitConv.mm2in(ptm.doubleValue()); | |||
pxToMillimeter = (float)(UnitConv.IN2MM / ptm.doubleValue()); | |||
} | |||
SVGUserAgent ua = new SVGUserAgent( | |||
pxToMillimeter, |
@@ -5,9 +5,9 @@ | |||
* The ASF licenses this file to You 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. | |||
@@ -16,7 +16,7 @@ | |||
*/ | |||
/* $Id$ */ | |||
package org.apache.fop.image.loader.batik; | |||
import java.awt.geom.AffineTransform; | |||
@@ -45,6 +45,7 @@ import org.apache.xmlgraphics.image.loader.impl.AbstractImagePreloader; | |||
import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; | |||
import org.apache.xmlgraphics.image.loader.util.ImageUtil; | |||
import org.apache.xmlgraphics.util.MimeConstants; | |||
import org.apache.xmlgraphics.util.UnitConv; | |||
import org.apache.fop.svg.SVGUserAgent; | |||
import org.apache.fop.util.UnclosableInputStream; | |||
@@ -58,8 +59,8 @@ public class PreloaderSVG extends AbstractImagePreloader { | |||
private static Log log = LogFactory.getLog(PreloaderSVG.class); | |||
private boolean batikAvailable = true; | |||
/** {@inheritDoc} */ | |||
/** {@inheritDoc} */ | |||
public ImageInfo preloadImage(String uri, Source src, ImageContext context) | |||
throws IOException { | |||
ImageInfo info = null; | |||
@@ -118,10 +119,10 @@ public class PreloaderSVG extends AbstractImagePreloader { | |||
in.mark(length + 1); | |||
SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory( | |||
getParserName()); | |||
doc = (SVGDocument) factory.createSVGDocument(src.getSystemId(), in); | |||
doc = factory.createSVGDocument(src.getSystemId(), in); | |||
} | |||
ImageInfo info = createImageInfo(uri, context, doc); | |||
return info; | |||
} catch (NoClassDefFoundError ncdfe) { | |||
if (in != null) { | |||
@@ -153,7 +154,7 @@ public class PreloaderSVG extends AbstractImagePreloader { | |||
private ImageInfo createImageInfo(String uri, ImageContext context, SVGDocument doc) { | |||
Element e = doc.getRootElement(); | |||
float pxUnitToMillimeter = 25.4f / context.getSourceResolution(); | |||
float pxUnitToMillimeter = UnitConv.IN2MM / context.getSourceResolution(); | |||
SVGUserAgent userAg = new SVGUserAgent(pxUnitToMillimeter, | |||
new AffineTransform()); | |||
BridgeContext ctx = new BridgeContext(userAg); | |||
@@ -176,9 +177,12 @@ public class PreloaderSVG extends AbstractImagePreloader { | |||
float height = UnitProcessor.svgVerticalLengthToUserSpace( | |||
s, SVGOMDocument.SVG_HEIGHT_ATTRIBUTE, uctx); | |||
int widthMpt = (int)Math.round(px2mpt(width, context.getSourceResolution())); | |||
int heightMpt = (int)Math.round(px2mpt(height, context.getSourceResolution())); | |||
ImageInfo info = new ImageInfo(uri, MimeConstants.MIME_SVG); | |||
ImageSize size = new ImageSize(); | |||
size.setSizeInMillipoints(Math.round(width * 1000), Math.round(height * 1000)); | |||
size.setSizeInMillipoints(widthMpt, heightMpt); | |||
//Set the resolution to that of the FOUserAgent | |||
size.setResolution(context.getSourceResolution()); | |||
size.calcPixelsFromSize(); | |||
@@ -190,7 +194,7 @@ public class PreloaderSVG extends AbstractImagePreloader { | |||
info.getCustomObjects().put(ImageInfo.ORIGINAL_IMAGE, xmlImage); | |||
return info; | |||
} | |||
private boolean isSupportedSource(Source src) { | |||
if (src instanceof DOMSource) { | |||
DOMSource domSrc = (DOMSource)src; | |||
@@ -202,4 +206,8 @@ public class PreloaderSVG extends AbstractImagePreloader { | |||
} | |||
private static double px2mpt(double px, double resolution) { | |||
return px * 1000 * UnitConv.IN2PT / resolution; | |||
} | |||
} |
@@ -1154,7 +1154,8 @@ public class RTFHandler extends FOEventHandler { | |||
FOUserAgent userAgent = ifo.getUserAgent(); | |||
ImageManager manager = userAgent.getFactory().getImageManager(); | |||
Image converted = manager.convertImage(image, FLAVORS); | |||
Map hints = ImageUtil.getDefaultHints(ua.getImageSessionContext()); | |||
Image converted = manager.convertImage(image, FLAVORS, hints); | |||
putGraphic(ifo, converted); | |||
} catch (Exception e) { |
@@ -60,6 +60,10 @@ | |||
--> | |||
<!--/release--> | |||
<release version="0.95" date="TBD"> | |||
<action context="Images" dev="JM" type="fix"> | |||
Fixed two bugs concerning resolution handling with SVG images and their | |||
conversion to bitmaps for RTF output. | |||
</action> | |||
<action context="Code" dev="JM" type="fix" fixes-bug="44887"> | |||
Fixed potential multi-threading problem concerning the use of DecimalFormat. | |||
</action> |
@@ -40,26 +40,26 @@ import org.apache.fop.apps.FopFactory; | |||
public class ImageLoaderTestCase extends TestCase { | |||
private static final File DEBUG_TARGET_DIR = null; //new File("D:/"); | |||
private FopFactory fopFactory; | |||
public ImageLoaderTestCase(String name) { | |||
super(name); | |||
fopFactory = FopFactory.newInstance(); | |||
fopFactory.setSourceResolution(72); | |||
fopFactory.setTargetResolution(300); | |||
} | |||
public void testSVG() throws Exception { | |||
String uri = "test/resources/images/img-w-size.svg"; | |||
FOUserAgent userAgent = fopFactory.newFOUserAgent(); | |||
ImageManager manager = fopFactory.getImageManager(); | |||
ImageInfo info = manager.preloadImage(uri, userAgent.getImageSessionContext()); | |||
assertNotNull("ImageInfo must not be null", info); | |||
Image img = manager.getImage(info, ImageFlavor.XML_DOM, | |||
Image img = manager.getImage(info, ImageFlavor.XML_DOM, | |||
userAgent.getImageSessionContext()); | |||
assertNotNull("Image must not be null", img); | |||
assertEquals(ImageFlavor.XML_DOM, img.getFlavor()); | |||
@@ -69,7 +69,7 @@ public class ImageLoaderTestCase extends TestCase { | |||
info = imgDom.getInfo(); //Switch to the ImageInfo returned by the image | |||
assertEquals(16000, info.getSize().getWidthMpt()); | |||
assertEquals(16000, info.getSize().getHeightMpt()); | |||
img = manager.getImage(info, ImageFlavor.RENDERED_IMAGE, | |||
userAgent.getImageSessionContext()); | |||
assertNotNull("Image must not be null", img); | |||
@@ -87,16 +87,61 @@ public class ImageLoaderTestCase extends TestCase { | |||
assertEquals(16000, info.getSize().getWidthMpt()); | |||
assertEquals(16000, info.getSize().getHeightMpt()); | |||
} | |||
public void testSVGNoViewbox() throws Exception { | |||
String uri = "test/resources/images/circles.svg"; | |||
FopFactory ff = FopFactory.newInstance(); | |||
ff.setSourceResolution(96); | |||
ff.setTargetResolution(300); | |||
FOUserAgent userAgent = ff.newFOUserAgent(); | |||
ImageManager manager = ff.getImageManager(); | |||
ImageInfo info = manager.preloadImage(uri, userAgent.getImageSessionContext()); | |||
assertNotNull("ImageInfo must not be null", info); | |||
Image img = manager.getImage(info, ImageFlavor.XML_DOM, | |||
userAgent.getImageSessionContext()); | |||
assertNotNull("Image must not be null", img); | |||
assertEquals(ImageFlavor.XML_DOM, img.getFlavor()); | |||
ImageXMLDOM imgDom = (ImageXMLDOM)img; | |||
assertNotNull(imgDom.getDocument()); | |||
assertEquals("http://www.w3.org/2000/svg", imgDom.getRootNamespace()); | |||
info = imgDom.getInfo(); //Switch to the ImageInfo returned by the image | |||
assertEquals(96, info.getSize().getDpiHorizontal(), 0); | |||
assertEquals(340158, info.getSize().getWidthMpt()); | |||
assertEquals(340158, info.getSize().getHeightMpt()); | |||
assertEquals(454, info.getSize().getWidthPx()); | |||
assertEquals(454, info.getSize().getHeightPx()); | |||
img = manager.getImage(info, ImageFlavor.RENDERED_IMAGE, | |||
userAgent.getImageSessionContext()); | |||
assertNotNull("Image must not be null", img); | |||
assertEquals(ImageFlavor.RENDERED_IMAGE, img.getFlavor()); | |||
ImageRendered imgRed = (ImageRendered)img; | |||
assertNotNull(imgRed.getRenderedImage()); | |||
if (DEBUG_TARGET_DIR != null) { | |||
ImageWriterUtil.saveAsPNG(imgRed.getRenderedImage(), | |||
(int)userAgent.getTargetResolution(), | |||
new File(DEBUG_TARGET_DIR, "circles.svg.png")); | |||
} | |||
assertEquals(1418, imgRed.getRenderedImage().getWidth()); | |||
assertEquals(1418, imgRed.getRenderedImage().getHeight()); | |||
info = imgRed.getInfo(); //Switch to the ImageInfo returned by the image | |||
assertEquals(340158, info.getSize().getWidthMpt()); | |||
assertEquals(340158, info.getSize().getHeightMpt()); | |||
} | |||
public void testWMF() throws Exception { | |||
String uri = "test/resources/images/testChart.wmf"; | |||
FOUserAgent userAgent = fopFactory.newFOUserAgent(); | |||
ImageManager manager = fopFactory.getImageManager(); | |||
ImageInfo info = manager.preloadImage(uri, userAgent.getImageSessionContext()); | |||
assertNotNull("ImageInfo must not be null", info); | |||
Image img = manager.getImage(info, ImageFlavor.RENDERED_IMAGE, | |||
userAgent.getImageSessionContext()); | |||
assertNotNull("Image must not be null", img); | |||
@@ -114,5 +159,5 @@ public class ImageLoaderTestCase extends TestCase { | |||
assertEquals(792000, info.getSize().getWidthMpt()); | |||
assertEquals(612000, info.getSize().getHeightMpt()); | |||
} | |||
} |
@@ -0,0 +1,8 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<svg xmlns="http://www.w3.org/2000/svg" width="12cm" height="12cm"> | |||
<g style="fill-opacity:0.7; stroke:black; stroke-width:0.1cm;"> | |||
<circle cx="6cm" cy="2cm" r="100" style="fill:red;" transform="translate(0,50)" /> | |||
<circle cx="6cm" cy="2cm" r="100" style="fill:blue;" transform="translate(70,150)" /> | |||
<circle cx="6cm" cy="2cm" r="100" style="fill:green;" transform="translate(-70,150)"/> | |||
</g> | |||
</svg> |