aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVincent Hennebert <vhennebert@apache.org>2012-03-19 15:56:19 +0000
committerVincent Hennebert <vhennebert@apache.org>2012-03-19 15:56:19 +0000
commitc1653ad47548cff23a614559544fe0b0aec3522d (patch)
tree07a0ab82acf33280d8560bf0e5d33fe683415f1b /src
parent0e6c4648996b5bfd38330129fcdfaaa72f86b09c (diff)
downloadxmlgraphics-fop-c1653ad47548cff23a614559544fe0b0aec3522d.tar.gz
xmlgraphics-fop-c1653ad47548cff23a614559544fe0b0aec3522d.zip
Bugzilla #51385: Added configuration option to set the version of the output PDF document.
Patch by Mehdi Houshmand, applied with minor modifications git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1302518 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/documentation/content/xdocs/trunk/configuration.xml14
-rw-r--r--src/java/org/apache/fop/pdf/PDFDocument.java60
-rw-r--r--src/java/org/apache/fop/pdf/PDFEmbeddedFile.java2
-rw-r--r--src/java/org/apache/fop/pdf/PDFInfo.java66
-rw-r--r--src/java/org/apache/fop/pdf/PDFObject.java70
-rw-r--r--src/java/org/apache/fop/pdf/PDFProfile.java4
-rw-r--r--src/java/org/apache/fop/pdf/PDFRoot.java15
-rw-r--r--src/java/org/apache/fop/pdf/Version.java71
-rw-r--r--src/java/org/apache/fop/pdf/VersionController.java121
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java2
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java18
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java26
12 files changed, 370 insertions, 99 deletions
diff --git a/src/documentation/content/xdocs/trunk/configuration.xml b/src/documentation/content/xdocs/trunk/configuration.xml
index cd1e1dfc3..10769c5ff 100644
--- a/src/documentation/content/xdocs/trunk/configuration.xml
+++ b/src/documentation/content/xdocs/trunk/configuration.xml
@@ -395,6 +395,18 @@
<noprinthq/>
</encryption-params>
</renderer>]]></source>
+ <p>
+ By default FOP produces PDF files of version 1.4, but this can be changed in order to benefit
+ from features that appeared in newer versions of PDF. At the moment, only a few features from
+ PDF 1.5 have been implemented, but the configuration element will accept any value between
+ 1.4 and 1.7. This is the value that will appear in the PDF header, although only features up
+ to 1.5 will actually be used.
+ <source><![CDATA[
+ <renderer mime="application/pdf">
+ <version>1.5</version>
+ <!-- Versions 1.4, 1.5, 1.6 and 1.7 are accepted, all other values are invalid -->
+ </renderer>]]></source>
+ </p>
</section>
<section id="ps-renderer">
@@ -522,4 +534,4 @@ information it finds. Check if FOP finds what you expect.</li>
</section>
</body>
-</document> \ No newline at end of file
+</document>
diff --git a/src/java/org/apache/fop/pdf/PDFDocument.java b/src/java/org/apache/fop/pdf/PDFDocument.java
index e9206a1bb..e9886fc37 100644
--- a/src/java/org/apache/fop/pdf/PDFDocument.java
+++ b/src/java/org/apache/fop/pdf/PDFDocument.java
@@ -65,12 +65,6 @@ public class PDFDocument {
private static final Long LOCATION_PLACEHOLDER = new Long(0);
- /** Integer constant to represent PDF 1.3 */
- public static final int PDF_VERSION_1_3 = 3;
-
- /** Integer constant to represent PDF 1.4 */
- public static final int PDF_VERSION_1_4 = 4;
-
/** the encoding to use when converting strings to PDF commands */
public static final String ENCODING = "ISO-8859-1";
@@ -95,8 +89,8 @@ public class PDFDocument {
/** the objects themselves */
private List objects = new LinkedList();
- /** Indicates what PDF version is active */
- private int pdfVersion = PDF_VERSION_1_4;
+ /** Controls the PDF version of this document */
+ private VersionController versionController;
/** Indicates which PDF profiles are active (PDF/A, PDF/X etc.) */
private PDFProfile pdfProfile = new PDFProfile(this);
@@ -197,6 +191,24 @@ public class PDFDocument {
* @param prod the name of the producer of this pdf document
*/
public PDFDocument(String prod) {
+ this(prod, null);
+ versionController = VersionController.getDynamicVersionController(Version.V1_4, this);
+ }
+
+ /**
+ * Creates an empty PDF document.
+ *
+ * The constructor creates a /Root and /Pages object to
+ * track the document but does not write these objects until
+ * the trailer is written. Note that the object ID of the
+ * pages object is determined now, and the xref table is
+ * updated later. This allows Pages to refer to their
+ * Parent before we write it out.
+ *
+ * @param prod the name of the producer of this pdf document
+ * @param versionController the version controller of this PDF document
+ */
+ public PDFDocument(String prod, VersionController versionController) {
this.factory = new PDFFactory(this);
@@ -211,26 +223,32 @@ public class PDFDocument {
// Make the /Info record
this.info = getFactory().makeInfo(prod);
+
+ this.versionController = versionController;
+ }
+
+ /**
+ * Returns the current PDF version.
+ *
+ * @return returns the PDF version
+ */
+ public Version getPDFVersion() {
+ return versionController.getPDFVersion();
}
/**
- * @return the integer representing the active PDF version
- * (one of PDFDocument.PDF_VERSION_*)
+ * Sets the PDF version of this document.
+ *
+ * @param version the PDF version
+ * @throws IllegalStateException if the version of this PDF is not allowed to change.
*/
- public int getPDFVersion() {
- return this.pdfVersion;
+ public void setPDFVersion(Version version) {
+ versionController.setPDFVersion(version);
}
- /** @return the String representing the active PDF version */
+ /** @return the String representing the current PDF version */
public String getPDFVersionString() {
- switch (getPDFVersion()) {
- case PDF_VERSION_1_3:
- return "1.3";
- case PDF_VERSION_1_4:
- return "1.4";
- default:
- throw new IllegalStateException("Unsupported PDF version selected");
- }
+ return versionController.getPDFVersion().toString();
}
/** @return the PDF profile currently active. */
diff --git a/src/java/org/apache/fop/pdf/PDFEmbeddedFile.java b/src/java/org/apache/fop/pdf/PDFEmbeddedFile.java
index a5b44710a..dc0681405 100644
--- a/src/java/org/apache/fop/pdf/PDFEmbeddedFile.java
+++ b/src/java/org/apache/fop/pdf/PDFEmbeddedFile.java
@@ -34,7 +34,7 @@ public class PDFEmbeddedFile extends PDFStream {
super();
put("Type", new PDFName("EmbeddedFile"));
PDFDictionary params = new PDFDictionary();
- params.put("CreationDate", params.formatDateTime(new Date()));
+ params.put("CreationDate", PDFInfo.formatDateTime(new Date()));
put("Params", params);
}
diff --git a/src/java/org/apache/fop/pdf/PDFInfo.java b/src/java/org/apache/fop/pdf/PDFInfo.java
index dabd88685..3f3fb3b46 100644
--- a/src/java/org/apache/fop/pdf/PDFInfo.java
+++ b/src/java/org/apache/fop/pdf/PDFInfo.java
@@ -21,7 +21,11 @@ package org.apache.fop.pdf;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
/**
* class representing an /Info object
@@ -232,5 +236,67 @@ public class PDFInfo extends PDFObject {
return bout.toByteArray();
}
+ /**
+ * Returns a SimpleDateFormat instance for formatting PDF date-times.
+ * @return a new SimpleDateFormat instance
+ */
+ protected static SimpleDateFormat getPDFDateFormat() {
+ SimpleDateFormat df = new SimpleDateFormat("'D:'yyyyMMddHHmmss", Locale.ENGLISH);
+ df.setTimeZone(TimeZone.getTimeZone("GMT"));
+ return df;
+ }
+
+ /**
+ * Formats a date/time according to the PDF specification (D:YYYYMMDDHHmmSSOHH'mm').
+ * @param time date/time value to format
+ * @param tz the time zone
+ * @return the requested String representation
+ */
+ protected static String formatDateTime(Date time, TimeZone tz) {
+ Calendar cal = Calendar.getInstance(tz, Locale.ENGLISH);
+ cal.setTime(time);
+
+ int offset = cal.get(Calendar.ZONE_OFFSET);
+ offset += cal.get(Calendar.DST_OFFSET);
+
+ // DateFormat is operating on GMT so adjust for time zone offset
+ Date dt1 = new Date(time.getTime() + offset);
+ StringBuffer sb = new StringBuffer();
+ sb.append(getPDFDateFormat().format(dt1));
+
+ offset /= (1000 * 60); // Convert to minutes
+
+ if (offset == 0) {
+ sb.append('Z');
+ } else {
+ if (offset > 0) {
+ sb.append('+');
+ } else {
+ sb.append('-');
+ }
+ int offsetHour = Math.abs(offset / 60);
+ int offsetMinutes = Math.abs(offset % 60);
+ if (offsetHour < 10) {
+ sb.append('0');
+ }
+ sb.append(Integer.toString(offsetHour));
+ sb.append('\'');
+ if (offsetMinutes < 10) {
+ sb.append('0');
+ }
+ sb.append(Integer.toString(offsetMinutes));
+ sb.append('\'');
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Formats a date/time according to the PDF specification. (D:YYYYMMDDHHmmSSOHH'mm').
+ * @param time date/time value to format
+ * @return the requested String representation
+ */
+ protected static String formatDateTime(Date time) {
+ return formatDateTime(time, TimeZone.getDefault());
+ }
}
diff --git a/src/java/org/apache/fop/pdf/PDFObject.java b/src/java/org/apache/fop/pdf/PDFObject.java
index d74133222..5abb5a142 100644
--- a/src/java/org/apache/fop/pdf/PDFObject.java
+++ b/src/java/org/apache/fop/pdf/PDFObject.java
@@ -23,11 +23,6 @@ package org.apache.fop.pdf;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -340,71 +335,6 @@ public abstract class PDFObject implements PDFWritable {
}
/**
- * Returns a SimpleDateFormat instance for formatting PDF date-times.
- * @return a new SimpleDateFormat instance
- */
- protected SimpleDateFormat getPDFDateFormat() {
- SimpleDateFormat df = new SimpleDateFormat("'D:'yyyyMMddHHmmss", Locale.ENGLISH);
- df.setTimeZone(TimeZone.getTimeZone("GMT"));
- return df;
- }
-
- /**
- * Formats a date/time according to the PDF specification
- * (D:YYYYMMDDHHmmSSOHH'mm').
- * @param time date/time value to format
- * @param tz the time zone
- * @return the requested String representation
- */
- protected String formatDateTime(Date time, TimeZone tz) {
- Calendar cal = Calendar.getInstance(tz, Locale.ENGLISH);
- cal.setTime(time);
-
- int offset = cal.get(Calendar.ZONE_OFFSET);
- offset += cal.get(Calendar.DST_OFFSET);
-
- //DateFormat is operating on GMT so adjust for time zone offset
- Date dt1 = new Date(time.getTime() + offset);
- StringBuffer sb = new StringBuffer();
- sb.append(getPDFDateFormat().format(dt1));
-
- offset /= (1000 * 60); //Convert to minutes
-
- if (offset == 0) {
- sb.append('Z');
- } else {
- if (offset > 0) {
- sb.append('+');
- } else {
- sb.append('-');
- }
- int offsetHour = Math.abs(offset / 60);
- int offsetMinutes = Math.abs(offset % 60);
- if (offsetHour < 10) {
- sb.append('0');
- }
- sb.append(Integer.toString(offsetHour));
- sb.append('\'');
- if (offsetMinutes < 10) {
- sb.append('0');
- }
- sb.append(Integer.toString(offsetMinutes));
- sb.append('\'');
- }
- return sb.toString();
- }
-
- /**
- * Formats a date/time according to the PDF specification.
- * (D:YYYYMMDDHHmmSSOHH'mm').
- * @param time date/time value to format
- * @return the requested String representation
- */
- protected String formatDateTime(Date time) {
- return formatDateTime(time, TimeZone.getDefault());
- }
-
- /**
* Check if the other PDFObject has the same content as the current object.
* <p>
* Note: This function has a contract which is less binding than
diff --git a/src/java/org/apache/fop/pdf/PDFProfile.java b/src/java/org/apache/fop/pdf/PDFProfile.java
index b4b43c422..580a9a791 100644
--- a/src/java/org/apache/fop/pdf/PDFProfile.java
+++ b/src/java/org/apache/fop/pdf/PDFProfile.java
@@ -184,11 +184,11 @@ public class PDFProfile {
public void verifyPDFVersion() {
final String err = "PDF version must be 1.4 for {0}";
if (getPDFAMode().isPDFA1LevelB()
- && getDocument().getPDFVersion() != PDFDocument.PDF_VERSION_1_4) {
+ && !Version.V1_4.equals(getDocument().getPDFVersion())) {
throw new PDFConformanceException(format(err, getPDFAMode()));
}
if (getPDFXMode() == PDFXMode.PDFX_3_2003
- && getDocument().getPDFVersion() != PDFDocument.PDF_VERSION_1_4) {
+ && !Version.V1_4.equals(getDocument().getPDFVersion())) {
throw new PDFConformanceException(format(err, getPDFXMode()));
}
}
diff --git a/src/java/org/apache/fop/pdf/PDFRoot.java b/src/java/org/apache/fop/pdf/PDFRoot.java
index 76f2587de..81b93b159 100644
--- a/src/java/org/apache/fop/pdf/PDFRoot.java
+++ b/src/java/org/apache/fop/pdf/PDFRoot.java
@@ -205,7 +205,7 @@ public class PDFRoot extends PDFDictionary {
* @since PDF 1.4
*/
public void setMetadata(PDFMetadata meta) {
- if (getDocumentSafely().getPDFVersion() >= PDFDocument.PDF_VERSION_1_4) {
+ if (getDocumentSafely().getPDFVersion().compareTo(Version.V1_4) >= 0) {
put("Metadata", meta.makeReference());
}
}
@@ -235,7 +235,7 @@ public class PDFRoot extends PDFDictionary {
* @since PDF 1.4
*/
public void addOutputIntent(PDFOutputIntent outputIntent) {
- if (getDocumentSafely().getPDFVersion() >= PDFDocument.PDF_VERSION_1_4) {
+ if (getDocumentSafely().getPDFVersion().compareTo(Version.V1_4) >= 0) {
PDFArray outputIntents = getOutputIntents();
if (outputIntents == null) {
outputIntents = new PDFArray(this);
@@ -246,6 +246,17 @@ public class PDFRoot extends PDFDictionary {
}
/**
+ * Sets the "Version" entry. If this version is greater than that specified in the header, this
+ * version takes precedence.
+ *
+ * @param version the PDF document version
+ * @since PDF 1.4
+ */
+ void setVersion(Version version) {
+ put("Version", new PDFName(version.toString()));
+ }
+
+ /**
* Returns the language identifier of the document.
* @return the language identifier of the document (or null if not set or undefined)
* @since PDF 1.4
diff --git a/src/java/org/apache/fop/pdf/Version.java b/src/java/org/apache/fop/pdf/Version.java
new file mode 100644
index 000000000..0df63d312
--- /dev/null
+++ b/src/java/org/apache/fop/pdf/Version.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.pdf;
+
+/**
+ * A version of PDF. Values are ordered such that compareTo() gives sensible
+ * results (e.g., {@code V1_4.compareTo(V1_5) < 0}).
+ */
+public enum Version {
+ /** PDF v1 */
+ V1_0("1.0"),
+ /** PDF v1.1 */
+ V1_1("1.1"),
+ /** PDF v1.2 */
+ V1_2("1.2"),
+ /** PDF v1.3 */
+ V1_3("1.3"),
+ /** PDF v1.4 */
+ V1_4("1.4"),
+ /** PDF v1.5 */
+ V1_5("1.5"),
+ /** PDF v1.6 */
+ V1_6("1.6"),
+ /** PDF v1.7 */
+ V1_7("1.7");
+
+ private String version;
+
+ private Version(String version) {
+ this.version = version;
+ }
+
+ /**
+ * Given the PDF version as a String, returns the corresponding enumerated type. The String
+ * should be in the format "1.x" for PDF v1.x.
+ *
+ * @param version a version number
+ * @return the corresponding Version instance
+ * @throws IllegalArgumentException if the argument does not correspond to any existing PDF version
+ */
+ public static Version getValueOf(String version) {
+ for (Version pdfVersion : Version.values()) {
+ if (pdfVersion.toString().equals(version)) {
+ return pdfVersion;
+ }
+ }
+ throw new IllegalArgumentException("Invalid PDF version given: " + version);
+ }
+
+ @Override
+ public String toString() {
+ return version;
+ }
+}
diff --git a/src/java/org/apache/fop/pdf/VersionController.java b/src/java/org/apache/fop/pdf/VersionController.java
new file mode 100644
index 000000000..4a92f4994
--- /dev/null
+++ b/src/java/org/apache/fop/pdf/VersionController.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.pdf;
+
+/**
+ * An abstraction that controls the mutability of the PDF version for a document.
+ */
+public abstract class VersionController {
+
+ private Version version;
+
+ private VersionController(Version version) {
+ this.version = version;
+ }
+
+ /**
+ * Returns the PDF version of the document.
+ *
+ * @return the PDF version
+ */
+ public Version getPDFVersion() {
+ return version;
+ }
+
+ /**
+ * Sets the PDF version of the document.
+ *
+ * @param version the PDF version
+ * @throws IllegalStateException if the PDF version is not allowed to change.
+ */
+ public abstract void setPDFVersion(Version version);
+
+ @Override
+ public String toString() {
+ return version.toString();
+ }
+
+ /**
+ * A class representing the version of a PDF document. This class doesn't allow the version to
+ * change once it has been set, it is immutable. Any attempt to set the version will result in
+ * an exception being thrown.
+ */
+ private static final class FixedVersion extends VersionController {
+
+ private FixedVersion(Version version) {
+ super(version);
+ }
+
+ @Override
+ public void setPDFVersion(Version version) {
+ throw new IllegalStateException("Cannot change the version of this PDF document.");
+ }
+ }
+
+ /**
+ * A class representing the version of a PDF document. This class allows the version to be
+ * changed once it has been set (it is mutable) ONLY if the new version is greater. If the PDF
+ * version is changed after it has been instantiated, the version will be set in the document
+ * catalog.
+ */
+ private static final class DynamicVersion extends VersionController {
+
+ private PDFDocument doc;
+
+ private DynamicVersion(Version version, PDFDocument doc) {
+ super(version);
+ this.doc = doc;
+ }
+
+ @Override
+ public void setPDFVersion(Version version) {
+ if (super.version.compareTo(version) < 0) {
+ super.version = version;
+ doc.getRoot().setVersion(version);
+ }
+ }
+ }
+
+ /**
+ * Returns a controller that disallows subsequent change to the document's version. The minimum
+ * allowed version is v1.4.
+ *
+ * @param version the PDF version (must be &gt;= v1.4)
+ * @return the fixed PDF version controller
+ */
+ public static VersionController getFixedVersionController(Version version) {
+ if (version.compareTo(Version.V1_4) < 0) {
+ throw new IllegalArgumentException("The PDF version cannot be set below version 1.4");
+ }
+ return new FixedVersion(version);
+ }
+
+ /**
+ * Returns a controller that allows subsequent changes to the document's version.
+ *
+ * @param initialVersion the initial PDF version
+ * @param doc the document whose version is being set
+ * @return the dynamic PDF version controller
+ */
+ public static VersionController getDynamicVersionController(Version initialVersion,
+ PDFDocument doc) {
+ return new DynamicVersion(initialVersion, doc);
+ }
+}
diff --git a/src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java b/src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java
index 994cbc0de..4a8a03b27 100644
--- a/src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java
+++ b/src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java
@@ -74,6 +74,8 @@ public interface PDFConfigurationConstants {
String PDF_X_MODE = "pdf-x-mode";
/** Rendering Options key for the ICC profile for the output intent. */
String KEY_OUTPUT_PROFILE = "output-profile";
+ /** PDF version entry: specify the version of the PDF document created, datatype: String */
+ String PDF_VERSION = "version";
/**
* Rendering Options key for disabling the sRGB color space (only possible if no PDF/A or
* PDF/X profile is active).
diff --git a/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java b/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java
index dcc7dd32e..df5224c04 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java
@@ -157,6 +157,8 @@ public class PDFRendererConfigurator extends PrintRendererConfigurator {
pdfUtil.setDisableSRGBColorSpace(
disableColorSpaceConfig.getValueAsBoolean(false));
}
+
+ setPDFDocVersion(cfg, pdfUtil);
}
private int checkEncryptionLength(int encryptionLength) {
@@ -175,6 +177,22 @@ public class PDFRendererConfigurator extends PrintRendererConfigurator {
return correctEncryptionLength;
}
+ private void setPDFDocVersion(Configuration cfg, PDFRenderingUtil pdfUtil) throws FOPException {
+ Configuration pdfVersion = cfg.getChild(PDFConfigurationConstants.PDF_VERSION, false);
+ if (pdfVersion != null) {
+ String version = pdfVersion.getValue(null);
+ if (version != null && version.length() != 0) {
+ try {
+ pdfUtil.setPDFVersion(version);
+ } catch (IllegalArgumentException e) {
+ throw new FOPException(e.getMessage());
+ }
+ } else {
+ throw new FOPException("The PDF version has not been set.");
+ }
+ }
+ }
+
/**
* Builds a filter map from an Avalon Configuration object.
*
diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java b/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java
index c662b0345..83f6ccab6 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java
@@ -64,6 +64,8 @@ import org.apache.fop.pdf.PDFPageLabels;
import org.apache.fop.pdf.PDFReference;
import org.apache.fop.pdf.PDFText;
import org.apache.fop.pdf.PDFXMode;
+import org.apache.fop.pdf.Version;
+import org.apache.fop.pdf.VersionController;
import org.apache.fop.render.pdf.extensions.PDFEmbeddedFileExtensionAttachment;
/**
@@ -102,6 +104,8 @@ class PDFRenderingUtil implements PDFConfigurationConstants {
/** Optional URI to an output profile to be used. */
protected String outputProfileURI;
+ protected Version maxPDFVersion;
+
PDFRenderingUtil(FOUserAgent userAgent) {
this.userAgent = userAgent;
@@ -375,8 +379,16 @@ class PDFRenderingUtil implements PDFConfigurationConstants {
if (this.pdfDoc != null) {
throw new IllegalStateException("PDFDocument already set up");
}
- this.pdfDoc = new PDFDocument(
- userAgent.getProducer() != null ? userAgent.getProducer() : "");
+
+ String producer = userAgent.getProducer() != null ? userAgent.getProducer() : "";
+
+ if (maxPDFVersion == null) {
+ this.pdfDoc = new PDFDocument(producer);
+ } else {
+ VersionController controller =
+ VersionController.getFixedVersionController(maxPDFVersion);
+ this.pdfDoc = new PDFDocument(producer, controller);
+ }
updateInfo();
updatePDFProfiles();
pdfDoc.setFilterMap(filterMap);
@@ -482,4 +494,14 @@ class PDFRenderingUtil implements PDFConfigurationConstants {
nameArray.add(new PDFReference(fileSpec));
}
+ /**
+ * Sets the PDF version of the output document. See {@link Version} for the format of
+ * <code>version</code>.
+ * @param version the PDF version
+ * @throws IllegalArgumentException if the format of version doesn't conform to that specified
+ * by {@link Version}
+ */
+ public void setPDFVersion(String version) {
+ maxPDFVersion = Version.getValueOf(version);
+ }
}