Resolution parameter to the user agent is split into: - a source resolution used to determine the pixel size in SVG images and bitmap without resolution information - a target resolution used to specify the output resolution of bitmap images generated by bitmap renderers and bitmaps generated by Batik for filter effects. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@357081 13f79535-47bb-0310-9956-ffa450edef68pull/16/head
@@ -16,8 +16,12 @@ the location of this file. | |||
<!-- Base URL for resolving relative URLs --> | |||
<base>.</base> | |||
<!-- Internal resolution in dpi (dots/pixels per inch), default: 72dpi --> | |||
<resolution>72</resolution> | |||
<!-- Source resolution in dpi (dots/pixels per inch) for determining the size of pixels in SVG and bitmap images, default: 72dpi --> | |||
<source-resolution>72</source-resolution> | |||
<!-- Target resolution in dpi (dots/pixels per inch) for specifying the target resolution for generated bitmaps, default: 72dpi --> | |||
<target-resolution>72</target-resolution> | |||
<!-- Default page-height and page-width, in case | |||
value is specified as auto --> | |||
<default-page-settings height="11in" width="8.26in"/> |
@@ -71,9 +71,21 @@ | |||
<td>Specifies the base URL based on which relative URL will be resolved.</td> | |||
</tr> | |||
<tr> | |||
<td>resolution</td> | |||
<td>source-resolution</td> | |||
<td>Integer, dpi</td> | |||
<td>Resolution in dpi (dots per inch) which is used internally.</td> | |||
<td> | |||
Resolution in dpi (dots per inch) which is used internally to determine the pixel | |||
size for SVG images and bitmap images without resolution information. | |||
</td> | |||
</tr> | |||
<tr> | |||
<td>target-resolution</td> | |||
<td>Integer, dpi</td> | |||
<td> | |||
Resolution in dpi (dots per inch) used to specify the output resolution for bitmap | |||
images generated by bitmap renderers (such as the TIFF renderer) and by bitmaps | |||
generated by Apache Batik for filter effects and such. | |||
</td> | |||
</tr> | |||
<tr> | |||
<td>strict-validation</td> | |||
@@ -119,8 +131,12 @@ | |||
<!-- Base URL for resolving relative URLs --> | |||
<base>./</base> | |||
<!-- Internal resolution in dpi (dots per pixel), default: 72dpi --> | |||
<resolution>72</resolution> | |||
<!-- Source resolution in dpi (dots/pixels per inch) for determining the size of pixels in SVG and bitmap images, default: 72dpi --> | |||
<source-resolution>72</source-resolution> | |||
<!-- Target resolution in dpi (dots/pixels per inch) for specifying the target resolution for generated bitmaps, default: 72dpi --> | |||
<target-resolution>72</target-resolution> | |||
<!-- default page-height and page-width, in case | |||
value is specified as auto --> | |||
<default-page-settings height="11in" width="8.26in"/> |
@@ -316,9 +316,19 @@ Fop fop = new Fop(MimeConstants.MIME_POSTSCRIPT, userAgent);]]></source> | |||
</li> | |||
<li> | |||
<p> | |||
Set the <strong>internal resolution</strong> for the document. This is used when creating bitmap images, for example. Example: | |||
Set the <strong>source resolution</strong> for the document. This is used internally to determine the pixel | |||
size for SVG images and bitmap images without resolution information. Default: 72 dpi. Example: | |||
</p> | |||
<source>userAgent.setResolution(300); //=300dpi (dots/pixels per Inch)</source> | |||
<source>userAgent.setSourceResolution(96); //=96dpi (dots/pixels per Inch)</source> | |||
</li> | |||
<li> | |||
<p> | |||
Set the <strong>target resolution</strong> for the document. This is used to | |||
specify the output resolution for bitmap images generated by bitmap renderers | |||
(such as the TIFF renderer) and by bitmaps generated by Apache Batik for filter | |||
effects and such. Default: 72 dpi. Example: | |||
</p> | |||
<source>userAgent.setTargetResolution(300); //=300dpi (dots/pixels per Inch)</source> | |||
</li> | |||
<li> | |||
<p> |
@@ -119,7 +119,7 @@ Fop [options] [-fo|-xml] infile [-xsl file] [-awt|-pdf|-mif|-rtf|-tiff|-png|-pcl | |||
-c cfg.xml use additional configuration file cfg.xml | |||
-l lang the language to use for user information | |||
-r relaxed/less strict validation (where available) | |||
-dpi xxx resolution in dots per inch (dpi) where xxx is a number | |||
-dpi xxx target resolution in dots per inch (dpi) where xxx is a number | |||
-s for area tree XML, down to block areas only | |||
-v to show FOP version being used | |||
@@ -70,10 +70,10 @@ import org.apache.fop.render.XMLHandlerRegistry; | |||
*/ | |||
public class FOUserAgent { | |||
/** Defines the default resolution (72dpi) for FOP */ | |||
public static final float DEFAULT_RESOLUTION = 72.0f; //dpi | |||
/** Defines the default resolution (72dpi) for FOP */ | |||
public static final float DEFAULT_PX2MM = (25.4f / DEFAULT_RESOLUTION); //dpi (=25.4/dpi) | |||
/** Defines the default source resolution (72dpi) for FOP */ | |||
public static final float DEFAULT_SOURCE_RESOLUTION = 72.0f; //dpi | |||
/** Defines the default target resolution (72dpi) for FOP */ | |||
public static final float DEFAULT_TARGET_RESOLUTION = 72.0f; //dpi | |||
/** Defines the default page-height */ | |||
public static final String DEFAULT_PAGE_HEIGHT = "11in"; | |||
/** Defines the default page-width */ | |||
@@ -93,7 +93,8 @@ public class FOUserAgent { | |||
private URIResolver foURIResolver = new FOURIResolver(); | |||
private PDFEncryptionParams pdfEncryptionParams; | |||
private float resolution = DEFAULT_RESOLUTION; | |||
private float sourceResolution = DEFAULT_SOURCE_RESOLUTION; | |||
private float targetResolution = DEFAULT_TARGET_RESOLUTION; | |||
private String pageHeight = DEFAULT_PAGE_HEIGHT; | |||
private String pageWidth = DEFAULT_PAGE_WIDTH; | |||
private Map rendererOptions = new java.util.HashMap(); | |||
@@ -411,16 +412,19 @@ public class FOUserAgent { | |||
} | |||
log.info("Base URL set to: " + baseURL); | |||
} | |||
if (userConfig.getChild("pixelToMillimeter", false) != null) { | |||
this.resolution = 25.4f / userConfig.getChild("pixelToMillimeter") | |||
.getAttributeAsFloat("value", DEFAULT_PX2MM); | |||
log.info("resolution set to: " + resolution | |||
+ "dpi (px2mm=" + getPixelUnitToMillimeter() + ")"); | |||
} else if (userConfig.getChild("resolution", false) != null) { | |||
this.resolution | |||
= userConfig.getChild("resolution").getValueAsFloat(DEFAULT_RESOLUTION); | |||
log.info("resolution set to: " + resolution | |||
+ "dpi (px2mm=" + getPixelUnitToMillimeter() + ")"); | |||
if (userConfig.getChild("source-resolution", false) != null) { | |||
this.sourceResolution | |||
= userConfig.getChild("source-resolution").getValueAsFloat( | |||
DEFAULT_SOURCE_RESOLUTION); | |||
log.info("Source resolution set to: " + sourceResolution | |||
+ "dpi (px2mm=" + getSourcePixelUnitToMillimeter() + ")"); | |||
} | |||
if (userConfig.getChild("target-resolution", false) != null) { | |||
this.targetResolution | |||
= userConfig.getChild("target-resolution").getValueAsFloat( | |||
DEFAULT_TARGET_RESOLUTION); | |||
log.info("Target resolution set to: " + targetResolution | |||
+ "dpi (px2mm=" + getTargetPixelUnitToMillimeter() + ")"); | |||
} | |||
if (userConfig.getChild("strict-validation", false) != null) { | |||
this.strictValidation = userConfig.getChild("strict-validation").getValueAsBoolean(); | |||
@@ -568,24 +572,51 @@ public class FOUserAgent { | |||
/** | |||
* Returns the conversion factor from pixel units to millimeters. This | |||
* depends on the desired reolution. | |||
* depends on the desired source resolution. | |||
* @return float conversion factor | |||
* @see getSourceResolution() | |||
*/ | |||
public float getSourcePixelUnitToMillimeter() { | |||
return 25.4f / this.sourceResolution; | |||
} | |||
/** | |||
* Returns the conversion factor from pixel units to millimeters. This | |||
* depends on the desired target resolution. | |||
* @return float conversion factor | |||
* @see getTargetResolution() | |||
*/ | |||
public float getPixelUnitToMillimeter() { | |||
return 25.4f / this.resolution; | |||
public float getTargetPixelUnitToMillimeter() { | |||
return 25.4f / this.targetResolution; | |||
} | |||
/** @return the resolution for resolution-dependant input */ | |||
public float getSourceResolution() { | |||
return this.sourceResolution; | |||
} | |||
/** @return the resolution for resolution-dependant output */ | |||
public float getResolution() { | |||
return this.resolution; | |||
public float getTargetResolution() { | |||
return this.targetResolution; | |||
} | |||
/** | |||
* Sets the resolution in dpi. | |||
* Sets the source resolution in dpi. This value is used to interpret the pixel size | |||
* of source documents like SVG images and bitmap images without resolution information. | |||
* @param dpi resolution in dpi | |||
*/ | |||
public void setSourceResolution(int dpi) { | |||
this.sourceResolution = dpi; | |||
} | |||
/** | |||
* Sets the target resolution in dpi. This value defines the target resolution of | |||
* bitmap images generated by the bitmap renderers (such as the TIFF renderer) and of | |||
* bitmap images generated by filter effects in Apache Batik. | |||
* @param dpi resolution in dpi | |||
*/ | |||
public void setResolution(int dpi) { | |||
this.resolution = dpi; | |||
public void setTargetResolution(int dpi) { | |||
this.targetResolution = dpi; | |||
} | |||
/** |
@@ -291,7 +291,7 @@ public class CommandLineOptions implements Constants { | |||
throw new FOPException( | |||
"if you use '-dpi', you must specify a resolution (dots per inch)"); | |||
} else { | |||
foUserAgent.setResolution(Integer.parseInt(args[i + 1])); | |||
foUserAgent.setTargetResolution(Integer.parseInt(args[i + 1])); | |||
return 1; | |||
} | |||
} | |||
@@ -769,7 +769,7 @@ public class CommandLineOptions implements Constants { | |||
+ " -c cfg.xml use additional configuration file cfg.xml\n" | |||
+ " -l lang the language to use for user information \n" | |||
+ " -r relaxed/less strict validation (where available)\n" | |||
+ " -dpi xxx resolution in dots per inch (dpi) where xxx is a number\n" | |||
+ " -dpi xxx target resolution in dots per inch (dpi) where xxx is a number\n" | |||
+ " -s for area tree XML, down to block areas only\n" | |||
+ " -v to show FOP version being used\n\n" | |||
+ " -o [password] PDF file will be encrypted with option owner password\n" |
@@ -94,7 +94,7 @@ public class SVGElement extends SVGObj { | |||
} | |||
Element e = ((SVGDocument)doc).getRootElement(); | |||
final float ptmm = getUserAgent().getPixelUnitToMillimeter(); | |||
final float ptmm = getUserAgent().getSourcePixelUnitToMillimeter(); | |||
// temporary svg context | |||
SVGContext dc = new SVGContext() { | |||
public float getPixelToMM() { | |||
@@ -153,7 +153,7 @@ public class SVGElement extends SVGObj { | |||
SVGDOMImplementation.SVG_NAMESPACE_URI); | |||
//} | |||
int fontSize = 12; | |||
Point2D p2d = getSize(fontSize, svgRoot, getUserAgent().getPixelUnitToMillimeter()); | |||
Point2D p2d = getSize(fontSize, svgRoot, getUserAgent().getSourcePixelUnitToMillimeter()); | |||
((SVGOMElement)e).setSVGContext(null); | |||
return p2d; |
@@ -90,7 +90,7 @@ public class SVGReader implements ImageReader { | |||
try { | |||
Loader loader = new Loader(); | |||
return loader.getImage(uri, bis, | |||
ua.getPixelUnitToMillimeter()); | |||
ua.getSourcePixelUnitToMillimeter()); | |||
} catch (NoClassDefFoundError e) { | |||
batik = false; | |||
log.warn("Batik not in class path", e); |
@@ -142,9 +142,11 @@ public class AWTRenderer extends Java2DRenderer implements Pageable { | |||
pageWidth = (int) Math.round(bounds.getWidth() / 1000f); | |||
pageHeight = (int) Math.round(bounds.getHeight() / 1000f); | |||
double scaleX = scaleFactor | |||
* FOUserAgent.DEFAULT_PX2MM / userAgent.getPixelUnitToMillimeter(); | |||
* (25.4 / FOUserAgent.DEFAULT_TARGET_RESOLUTION) | |||
/ userAgent.getTargetPixelUnitToMillimeter(); | |||
double scaleY = scaleFactor | |||
* FOUserAgent.DEFAULT_PX2MM / userAgent.getPixelUnitToMillimeter(); | |||
* (25.4 / FOUserAgent.DEFAULT_TARGET_RESOLUTION) | |||
/ userAgent.getTargetPixelUnitToMillimeter(); | |||
int bitmapWidth = (int) ((pageWidth * scaleX) + 0.5); | |||
int bitmapHeight = (int) ((pageHeight * scaleY) + 0.5); | |||
return new Dimension(bitmapWidth, bitmapHeight); |
@@ -118,7 +118,7 @@ public class PNGRenderer extends Java2DRenderer { | |||
renderParams = PNGEncodeParam.getDefaultEncodeParam(image); | |||
// Set resolution | |||
float pixSzMM = userAgent.getPixelUnitToMillimeter(); | |||
float pixSzMM = userAgent.getTargetPixelUnitToMillimeter(); | |||
// num Pixs in 1 Meter | |||
int numPix = (int)((1000 / pixSzMM) + 0.5); | |||
renderParams.setPhysicalDimension(numPix, numPix, 1); // 1 means 'pix/meter' |
@@ -130,8 +130,8 @@ public class TIFFRenderer extends Java2DRenderer { | |||
super.stopRenderer(); | |||
log.debug("Starting Tiff encoding ..."); | |||
//Set resolution | |||
float pixSzMM = userAgent.getPixelUnitToMillimeter(); | |||
//Set target resolution | |||
float pixSzMM = userAgent.getTargetPixelUnitToMillimeter(); | |||
// num Pixs in 100 Meters | |||
int numPix = (int)(((1000 * 100) / pixSzMM) + 0.5); | |||
int denom = 100 * 100; // Centimeters per 100 Meters; |
@@ -274,9 +274,11 @@ public abstract class Java2DRenderer extends AbstractRenderer implements Printab | |||
+ pageHeight + ")"); | |||
double scaleX = scaleFactor | |||
* FOUserAgent.DEFAULT_PX2MM / userAgent.getPixelUnitToMillimeter(); | |||
* (25.4 / FOUserAgent.DEFAULT_TARGET_RESOLUTION) | |||
/ userAgent.getTargetPixelUnitToMillimeter(); | |||
double scaleY = scaleFactor | |||
* FOUserAgent.DEFAULT_PX2MM / userAgent.getPixelUnitToMillimeter(); | |||
* (25.4 / FOUserAgent.DEFAULT_TARGET_RESOLUTION) | |||
/ userAgent.getTargetPixelUnitToMillimeter(); | |||
int bitmapWidth = (int) ((pageWidth * scaleX) + 0.5); | |||
int bitmapHeight = (int) ((pageHeight * scaleY) + 0.5); | |||
@@ -157,7 +157,7 @@ public class Java2DSVGHandler implements XMLHandler { | |||
int x = info.currentXPosition; | |||
int y = info.currentYPosition; | |||
float ptom = context.getUserAgent().getPixelUnitToMillimeter(); | |||
float ptom = context.getUserAgent().getSourcePixelUnitToMillimeter(); | |||
SVGUserAgent ua = new SVGUserAgent(ptom, new AffineTransform()); | |||
GVTBuilder builder = new GVTBuilder(); |
@@ -27,8 +27,6 @@ import org.apache.fop.pdf.PDFState; | |||
import org.apache.fop.pdf.PDFStream; | |||
import org.apache.fop.pdf.PDFResourceContext; | |||
import org.apache.fop.svg.PDFBridgeContext; | |||
import org.apache.fop.svg.PDFTextElementBridge; | |||
import org.apache.fop.svg.PDFAElementBridge; | |||
import org.apache.fop.svg.PDFGraphics2D; | |||
import org.apache.fop.svg.SVGUserAgent; | |||
import org.apache.fop.fonts.FontInfo; | |||
@@ -43,14 +41,12 @@ import org.apache.commons.logging.LogFactory; | |||
import java.io.OutputStream; | |||
import org.apache.batik.bridge.Bridge; | |||
import org.apache.batik.bridge.GVTBuilder; | |||
import org.apache.batik.bridge.BridgeContext; | |||
import org.apache.batik.bridge.ViewBox; | |||
import org.apache.batik.dom.svg.SVGDOMImplementation; | |||
import org.apache.batik.gvt.GraphicsNode; | |||
import org.apache.batik.util.SVGConstants; | |||
import org.w3c.dom.svg.SVGDocument; | |||
import org.w3c.dom.svg.SVGSVGElement; | |||
@@ -227,12 +223,11 @@ public class PDFSVGHandler implements XMLHandler { | |||
int yOffset = pdfInfo.currentYPosition; | |||
log.debug("Generating SVG at " | |||
+ context.getUserAgent().getResolution() | |||
+ context.getUserAgent().getTargetResolution() | |||
+ "dpi."); | |||
final float deviceResolution = context.getUserAgent().getTargetResolution(); | |||
final int uaResolution = 72; //Should not be changed | |||
final float deviceResolution | |||
= context.getUserAgent().getResolution(); | |||
final float uaResolution = context.getUserAgent().getSourceResolution(); | |||
SVGUserAgent ua = new SVGUserAgent(25.4f / uaResolution, new AffineTransform()); | |||
GVTBuilder builder = new GVTBuilder(); | |||
@@ -280,14 +275,16 @@ public class PDFSVGHandler implements XMLHandler { | |||
+ yOffset / 1000f + " cm\n"); | |||
SVGSVGElement svg = ((SVGDocument)doc).getRootElement(); | |||
//AffineTransform at = ViewBox.getPreserveAspectRatioTransform(svg, w / 1000f, h / 1000f); | |||
//AffineTransform at = ViewBox.getPreserveAspectRatioTransform( | |||
// svg, w / 1000f, h / 1000f); | |||
AffineTransform at = ViewBox.getPreserveAspectRatioTransform(svg, | |||
pdfInfo.width / 1000f, pdfInfo.height / 1000f); | |||
if (false && !at.isIdentity()) { | |||
/* | |||
if (!at.isIdentity()) { | |||
double[] vals = new double[6]; | |||
at.getMatrix(vals); | |||
pdfInfo.currentStream.add(CTMHelper.toPDFString(at, false) + " cm\n"); | |||
} | |||
}*/ | |||
if (pdfInfo.pdfContext == null) { | |||
pdfInfo.pdfContext = pdfInfo.pdfPage; |
@@ -261,7 +261,7 @@ public class PSSVGHandler implements XMLHandler { | |||
SVGUserAgent ua | |||
= new SVGUserAgent( | |||
context.getUserAgent().getPixelUnitToMillimeter(), | |||
context.getUserAgent().getSourcePixelUnitToMillimeter(), | |||
new AffineTransform()); | |||
GVTBuilder builder = new GVTBuilder(); |
@@ -27,6 +27,11 @@ | |||
<changes> | |||
<release version="FOP Trunk"> | |||
<action context="Code" dev="JM" type="fix"> | |||
Changed the way resolutions are handled. The single resolution in the user | |||
agent got split up into source and target resolutions. For more info, see | |||
the updated documentation. Note: backwards-incompatible change! | |||
</action> | |||
<action context="Code" dev="JM" type="fix" fixes-bug="37875"> | |||
Bugfix: Some content inside a table-header may not have been renderered on | |||
pages n > 1 in certain conditions. |
@@ -85,7 +85,7 @@ public abstract class AbstractPSPDFBitmapProducer extends AbstractBitmapProducer | |||
//Build command-line | |||
String cmd = MessageFormat.format(converter, | |||
new Object[] {inFile.toString(), outFile.toString(), | |||
Integer.toString(context.getResolution())}); | |||
Integer.toString(context.getTargetResolution())}); | |||
ConvertUtils.convert(cmd, null, null, log); | |||
if (!outFile.exists()) { | |||
@@ -107,7 +107,7 @@ public abstract class AbstractPSPDFBitmapProducer extends AbstractBitmapProducer | |||
public BufferedImage produce(File src, ProducerContext context) { | |||
try { | |||
FOUserAgent userAgent = new FOUserAgent(); | |||
userAgent.setResolution(context.getResolution()); | |||
userAgent.setTargetResolution(context.getTargetResolution()); | |||
userAgent.setBaseURL(src.getParentFile().toURL().toString()); | |||
File tempOut = new File(context.getTargetDir(), |
@@ -152,14 +152,14 @@ public class BatchDiffer { | |||
public void runBatch(Configuration cfg) { | |||
try { | |||
ProducerContext context = new ProducerContext(); | |||
context.setResolution(cfg.getChild("resolution").getValueAsInteger(72)); | |||
context.setTargetResolution(cfg.getChild("resolution").getValueAsInteger(72)); | |||
String xslt = cfg.getChild("stylesheet").getValue(null); | |||
if (xslt != null) { | |||
try { | |||
context.setTemplates(context.getTransformerFactory().newTemplates( | |||
new StreamSource(xslt))); | |||
} catch (TransformerConfigurationException e) { | |||
// throw new RuntimeException("Error setting up stylesheet", e); // This is JDK 1.4 or later specific | |||
log.error("Error setting up stylesheet", e); | |||
throw new RuntimeException("Error setting up stylesheet"); | |||
} | |||
} | |||
@@ -252,7 +252,7 @@ public class BatchDiffer { | |||
producers[i] = (BitmapProducer)clazz.newInstance(); | |||
ContainerUtil.configure(producers[i], children[i]); | |||
} catch (Exception e) { | |||
// throw new RuntimeException("Error while setting up producers", e); // This is JDK 1.4 or later specific | |||
log.error("Error setting up producers", e); | |||
throw new RuntimeException("Error while setting up producers"); | |||
} | |||
} |
@@ -35,7 +35,6 @@ import org.apache.commons.io.IOUtils; | |||
import org.apache.fop.apps.FOUserAgent; | |||
import org.apache.fop.apps.Fop; | |||
import org.apache.fop.apps.MimeConstants; | |||
import org.apache.fop.fo.Constants; | |||
/** | |||
* BitmapProducer implementation that uses the Java2DRenderer to create bitmaps. | |||
@@ -63,7 +62,7 @@ public class BitmapProducerJava2D extends AbstractBitmapProducer implements Conf | |||
public BufferedImage produce(File src, ProducerContext context) { | |||
try { | |||
FOUserAgent userAgent = new FOUserAgent(); | |||
userAgent.setResolution(context.getResolution()); | |||
userAgent.setTargetResolution(context.getTargetResolution()); | |||
userAgent.setBaseURL(src.getParentFile().toURL().toString()); | |||
File outputFile = new File(context.getTargetDir(), src.getName() + ".java2d.png"); |
@@ -30,7 +30,7 @@ public class ProducerContext { | |||
private TransformerFactory tFactory; | |||
private Templates templates; | |||
private int resolution; | |||
private int targetResolution; | |||
private File targetDir; | |||
/** | |||
@@ -46,16 +46,16 @@ public class ProducerContext { | |||
/** | |||
* @return the requested bitmap resolution in dpi for all bitmaps. | |||
*/ | |||
public int getResolution() { | |||
return resolution; | |||
public int getTargetResolution() { | |||
return targetResolution; | |||
} | |||
/** | |||
* Sets the requested bitmap resolution in dpi for all bitmaps. | |||
* @param resolution the resolution in dpi | |||
*/ | |||
public void setResolution(int resolution) { | |||
this.resolution = resolution; | |||
public void setTargetResolution(int resolution) { | |||
this.targetResolution = resolution; | |||
} | |||
/** |