aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Steiner <ssteiner@apache.org>2015-03-12 10:13:48 +0000
committerSimon Steiner <ssteiner@apache.org>2015-03-12 10:13:48 +0000
commitde3950df5e27c9e8a7901a3377891bfab9bb4b1c (patch)
treed2fa421d4740b3ae727eb0b6aec499230ece6bd8
parentb28c99c038ebe6ed1c9c8690a68a7c6deab97ff7 (diff)
downloadxmlgraphics-fop-de3950df5e27c9e8a7901a3377891bfab9bb4b1c.tar.gz
xmlgraphics-fop-de3950df5e27c9e8a7901a3377891bfab9bb4b1c.zip
FOP-2456: PDF VT and Page Piece support
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1666117 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--lib/xmlgraphics-commons-svn-trunk.jarbin632951 -> 637086 bytes
-rw-r--r--src/foschema/fop-configuration.xsd4
-rw-r--r--src/java/org/apache/fop/pdf/PDFDPart.java47
-rw-r--r--src/java/org/apache/fop/pdf/PDFDPartRoot.java42
-rw-r--r--src/java/org/apache/fop/pdf/PDFFactory.java22
-rw-r--r--src/java/org/apache/fop/pdf/PDFImageXObject.java7
-rw-r--r--src/java/org/apache/fop/pdf/PDFMetadata.java35
-rw-r--r--src/java/org/apache/fop/pdf/PDFProfile.java35
-rw-r--r--src/java/org/apache/fop/pdf/PDFRoot.java10
-rw-r--r--src/java/org/apache/fop/pdf/PDFVTMode.java45
-rw-r--r--src/java/org/apache/fop/pdf/PDFXMode.java12
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java3
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRendererConfig.java2
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRendererOption.java8
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java6
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java32
-rw-r--r--src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryElement.java4
-rw-r--r--src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryExtension.java2
-rw-r--r--src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryType.java4
-rw-r--r--src/java/org/apache/fop/render/pdf/extensions/PDFElementMapping.java15
-rw-r--r--src/java/org/apache/fop/render/pdf/extensions/PDFVTElement.java28
-rw-r--r--test/java/org/apache/fop/pdf/PDFLinearizationTestCase.java2
-rw-r--r--test/java/org/apache/fop/pdf/PDFPagePieceTestCase.java67
-rw-r--r--test/java/org/apache/fop/pdf/PDFVT.fo29
-rw-r--r--test/java/org/apache/fop/pdf/PDFVT.xconf15
-rw-r--r--test/java/org/apache/fop/pdf/PDFVTTestCase.java142
-rw-r--r--test/resources/color/ISOcoated_v2_300_bas.iccbin0 -> 1053552 bytes
27 files changed, 601 insertions, 17 deletions
diff --git a/lib/xmlgraphics-commons-svn-trunk.jar b/lib/xmlgraphics-commons-svn-trunk.jar
index 262c55b31..f0c861d6e 100644
--- a/lib/xmlgraphics-commons-svn-trunk.jar
+++ b/lib/xmlgraphics-commons-svn-trunk.jar
Binary files differ
diff --git a/src/foschema/fop-configuration.xsd b/src/foschema/fop-configuration.xsd
index 2201016d1..d3c0b3885 100644
--- a/src/foschema/fop-configuration.xsd
+++ b/src/foschema/fop-configuration.xsd
@@ -94,6 +94,9 @@
</xsd:annotation>
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:choice>
+ <xsd:element name="pdf-a-mode" type="xsd:string" minOccurs="0"/>
+ <xsd:element name="pdf-x-mode" type="xsd:string" minOccurs="0"/>
+ <xsd:element name="pdf-vt-mode" type="xsd:string" minOccurs="0"/>
<xsd:element name="version" type="xsd:float" minOccurs="0"/>
<xsd:element name="endianness" type="xsd:string" minOccurs="0">
<xsd:annotation>
@@ -271,6 +274,7 @@
</xsd:element>
<xsd:element name="resource-group-file" type="xsd:string" minOccurs="0"/>
<xsd:element name="default-resource-levels" minOccurs="0"/>
+ <xsd:element name="merge-fonts" minOccurs="0"/>
</xsd:choice>
</xsd:sequence>
<xsd:attribute name="mime" type="MimeConstants" use="required"/>
diff --git a/src/java/org/apache/fop/pdf/PDFDPart.java b/src/java/org/apache/fop/pdf/PDFDPart.java
new file mode 100644
index 000000000..bd7262713
--- /dev/null
+++ b/src/java/org/apache/fop/pdf/PDFDPart.java
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PDFDPart extends PDFDictionary {
+ private List<PDFPage> pages = new ArrayList<PDFPage>();
+ private PDFDictionary parent;
+ public PDFDPart(PDFDictionary parent) {
+ this.parent = parent;
+ put("Type", new PDFName("DPart"));
+ }
+
+ public void addPage(PDFPage p) {
+ pages.add(p);
+ }
+
+ @Override
+ public int output(OutputStream stream) throws IOException {
+ put("Parent", parent.makeReference());
+ if (!pages.isEmpty()) {
+ put("Start", pages.get(0).makeReference());
+ put("End", pages.get(pages.size() - 1).makeReference());
+ }
+ return super.output(stream);
+ }
+}
diff --git a/src/java/org/apache/fop/pdf/PDFDPartRoot.java b/src/java/org/apache/fop/pdf/PDFDPartRoot.java
new file mode 100644
index 000000000..cd1d3b446
--- /dev/null
+++ b/src/java/org/apache/fop/pdf/PDFDPartRoot.java
@@ -0,0 +1,42 @@
+/*
+ * 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;
+
+public class PDFDPartRoot extends PDFDictionary {
+ private PDFArray parts = new PDFArray();
+ protected PDFDPart dpart;
+
+ public PDFDPartRoot(PDFDocument document) {
+ put("Type", new PDFName("DPartRoot"));
+ dpart = new PDFDPart(this);
+ document.registerTrailerObject(dpart);
+ PDFArray dparts = new PDFArray();
+ dparts.add(parts);
+ dpart.put("DParts", dparts);
+ put("DPartRootNode", dpart.makeReference());
+ PDFArray nodeNameList = new PDFArray();
+ nodeNameList.add(new PDFName("root"));
+ nodeNameList.add(new PDFName("record"));
+ put("NodeNameList", nodeNameList);
+ }
+
+ public void add(PDFDPart part) {
+ parts.add(part);
+ }
+}
diff --git a/src/java/org/apache/fop/pdf/PDFFactory.java b/src/java/org/apache/fop/pdf/PDFFactory.java
index 86a480780..b1152df16 100644
--- a/src/java/org/apache/fop/pdf/PDFFactory.java
+++ b/src/java/org/apache/fop/pdf/PDFFactory.java
@@ -28,6 +28,7 @@ import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.BitSet;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -76,6 +77,7 @@ public class PDFFactory {
private Log log = LogFactory.getLog(PDFFactory.class);
private int subsetFontCounter = -1;
+ private Map<String, PDFDPart> dparts = new HashMap<String, PDFDPart>();
/**
* Creates a new PDFFactory.
@@ -1487,4 +1489,24 @@ public class PDFFactory {
return navigator;
}
+ public void makeDPart(PDFPage page, String pageMasterName) {
+ PDFDPartRoot root = getDocument().getRoot().getDPartRoot();
+ PDFDPart dPart;
+ if (dparts.containsKey(pageMasterName)) {
+ dPart = dparts.get(pageMasterName);
+ } else {
+ dPart = new PDFDPart(root.dpart);
+ root.add(dPart);
+ getDocument().registerTrailerObject(dPart);
+ dparts.put(pageMasterName, dPart);
+ }
+ dPart.addPage(page);
+ page.put("DPart", dPart);
+ }
+
+ public PDFDPartRoot makeDPartRoot() {
+ PDFDPartRoot pdfdPartRoot = new PDFDPartRoot(getDocument());
+ getDocument().registerTrailerObject(pdfdPartRoot);
+ return pdfdPartRoot;
+ }
}
diff --git a/src/java/org/apache/fop/pdf/PDFImageXObject.java b/src/java/org/apache/fop/pdf/PDFImageXObject.java
index e472efbea..bbee663da 100644
--- a/src/java/org/apache/fop/pdf/PDFImageXObject.java
+++ b/src/java/org/apache/fop/pdf/PDFImageXObject.java
@@ -20,9 +20,11 @@
package org.apache.fop.pdf;
// Java
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Set;
+import java.util.UUID;
/* modified by JKT to integrate with 0.12.0 */
/* modified by Eric SCHAEFFER to integrate with 0.13.0 */
@@ -63,6 +65,11 @@ public class PDFImageXObject extends PDFXObject {
* @return the length of the data written
*/
public int output(OutputStream stream) throws IOException {
+ if (getDocument().getProfile().isPDFVTActive()) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ pdfimage.outputContents(baos);
+ put("GTS_XID", "uuid:" + UUID.nameUUIDFromBytes(baos.toByteArray()));
+ }
int length = super.output(stream);
// let it gc
diff --git a/src/java/org/apache/fop/pdf/PDFMetadata.java b/src/java/org/apache/fop/pdf/PDFMetadata.java
index 203429147..370c0017a 100644
--- a/src/java/org/apache/fop/pdf/PDFMetadata.java
+++ b/src/java/org/apache/fop/pdf/PDFMetadata.java
@@ -22,6 +22,7 @@ package org.apache.fop.pdf;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
+import java.util.UUID;
import javax.xml.transform.TransformerConfigurationException;
@@ -37,6 +38,12 @@ import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFAdapter;
import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFSchema;
import org.apache.xmlgraphics.xmp.schemas.pdf.PDFAAdapter;
import org.apache.xmlgraphics.xmp.schemas.pdf.PDFAXMPSchema;
+import org.apache.xmlgraphics.xmp.schemas.pdf.PDFVTAdapter;
+import org.apache.xmlgraphics.xmp.schemas.pdf.PDFVTXMPSchema;
+import org.apache.xmlgraphics.xmp.schemas.pdf.PDFXAdapter;
+import org.apache.xmlgraphics.xmp.schemas.pdf.PDFXXMPSchema;
+import org.apache.xmlgraphics.xmp.schemas.pdf.XAPMMAdapter;
+import org.apache.xmlgraphics.xmp.schemas.pdf.XAPMMXMPSchema;
/**
* Special PDFStream for Metadata.
@@ -161,11 +168,35 @@ public class PDFMetadata extends PDFStream {
pdfa.setPart(pdfaMode.getPart());
pdfa.setConformance(String.valueOf(pdfaMode.getConformanceLevel()));
}
+ AdobePDFAdapter adobePDF = AdobePDFSchema.getAdapter(meta);
+ PDFXMode pdfxMode = pdfDoc.getProfile().getPDFXMode();
+ if (pdfxMode != PDFXMode.DISABLED) {
+ PDFXAdapter pdfx = PDFXXMPSchema.getAdapter(meta);
+ pdfx.setVersion(pdfxMode.getName());
+
+ XAPMMAdapter xapmm = XAPMMXMPSchema.getAdapter(meta);
+ xapmm.setVersion("1");
+ xapmm.setDocumentID("uuid:" + UUID.randomUUID().toString());
+ xapmm.setInstanceID("uuid:" + UUID.randomUUID().toString());
+ xapmm.setRenditionClass("default");
+ adobePDF.setTrapped("False");
+ }
+ PDFProfile profile = pdfDoc.getProfile();
+ PDFVTMode pdfvtMode = profile.getPDFVTMode();
+ if (pdfvtMode != PDFVTMode.DISABLED) {
+ PDFVTAdapter pdfvt = PDFVTXMPSchema.getAdapter(meta);
+ pdfvt.setVersion("PDF/VT-1");
+ if (info.getModDate() != null) {
+ pdfvt.setModifyDate(info.getModDate());
+ } else if (profile.isModDateRequired()) {
+ //if modify date is needed but none is in the Info object, use creation date
+ pdfvt.setModifyDate(info.getCreationDate());
+ }
+ }
//XMP Basic Schema
XMPBasicAdapter xmpBasic = XMPBasicSchema.getAdapter(meta);
xmpBasic.setCreateDate(info.getCreationDate());
- PDFProfile profile = pdfDoc.getProfile();
if (info.getModDate() != null) {
xmpBasic.setModifyDate(info.getModDate());
} else if (profile.isModDateRequired()) {
@@ -176,7 +207,7 @@ public class PDFMetadata extends PDFStream {
xmpBasic.setCreatorTool(info.getCreator());
}
- AdobePDFAdapter adobePDF = AdobePDFSchema.getAdapter(meta);
+
if (info.getKeywords() != null) {
adobePDF.setKeywords(info.getKeywords());
}
diff --git a/src/java/org/apache/fop/pdf/PDFProfile.java b/src/java/org/apache/fop/pdf/PDFProfile.java
index 4289d0ee8..219623842 100644
--- a/src/java/org/apache/fop/pdf/PDFProfile.java
+++ b/src/java/org/apache/fop/pdf/PDFProfile.java
@@ -43,6 +43,8 @@ public class PDFProfile {
*/
protected PDFXMode pdfXMode = PDFXMode.DISABLED;
+ protected PDFVTMode pdfVTMode = PDFVTMode.DISABLED;
+
private PDFDocument doc;
/**
@@ -59,12 +61,15 @@ public class PDFProfile {
protected void validateProfileCombination() {
if (pdfAMode != PDFAMode.DISABLED) {
if (pdfAMode == PDFAMode.PDFA_1B) {
- if (pdfXMode != PDFXMode.DISABLED && pdfXMode != PDFXMode.PDFX_3_2003) {
+ if (pdfXMode != PDFXMode.DISABLED && pdfXMode != PDFXMode.PDFX_3_2003 && pdfXMode != PDFXMode.PDFX_4) {
throw new PDFConformanceException(
pdfAMode + " and " + pdfXMode + " are not compatible!");
}
}
}
+ if (pdfVTMode != PDFVTMode.DISABLED && pdfXMode != PDFXMode.PDFX_4) {
+ throw new PDFConformanceException(pdfVTMode.name() + " requires " + PDFXMode.PDFX_4.getName() + " enabled");
+ }
}
/** @return the PDFDocument this profile is attached to */
@@ -99,11 +104,19 @@ public class PDFProfile {
return this.pdfXMode;
}
+ public PDFVTMode getPDFVTMode() {
+ return this.pdfVTMode;
+ }
+
/** @return true if any PDF/X mode is active */
public boolean isPDFXActive() {
return getPDFXMode() != PDFXMode.DISABLED;
}
+ public boolean isPDFVTActive() {
+ return getPDFVTMode() != PDFVTMode.DISABLED;
+ }
+
/**
* Sets the PDF/X mode
* @param mode the PDF/X mode
@@ -116,6 +129,18 @@ public class PDFProfile {
validateProfileCombination();
}
+ /**
+ * Sets the PDF/X mode
+ * @param mode the PDF/X mode
+ */
+ public void setPDFVTMode(PDFVTMode mode) {
+ if (mode == null) {
+ mode = PDFVTMode.DISABLED;
+ }
+ this.pdfVTMode = mode;
+ validateProfileCombination();
+ }
+
/** {@inheritDoc} */
public String toString() {
StringBuffer sb = new StringBuffer();
@@ -186,7 +211,7 @@ public class PDFProfile {
if (pdfAMode.isPart1()) {
return getPDFAMode();
}
- if (isPDFXActive()) {
+ if (getPDFXMode() == PDFXMode.PDFX_3_2003) {
return getPDFXMode();
}
return null;
@@ -194,7 +219,7 @@ public class PDFProfile {
/** Checks if the right PDF version is set. */
public void verifyPDFVersion() {
- final String err = "PDF version must be 1.4 for {0}";
+ String err = "PDF version must be 1.4 for {0}";
if (getPDFAMode().isPart1()
&& !Version.V1_4.equals(getDocument().getPDFVersion())) {
throw new PDFConformanceException(format(err, getPDFAMode()));
@@ -252,12 +277,12 @@ public class PDFProfile {
/** @return true if the ModDate Info entry must be present. */
public boolean isModDateRequired() {
- return getPDFXMode() == PDFXMode.PDFX_3_2003;
+ return getPDFXMode() != PDFXMode.DISABLED;
}
/** @return true if the Trapped Info entry must be present. */
public boolean isTrappedEntryRequired() {
- return getPDFXMode() == PDFXMode.PDFX_3_2003;
+ return getPDFXMode() != PDFXMode.DISABLED;
}
/** @return true if annotations are allowed */
diff --git a/src/java/org/apache/fop/pdf/PDFRoot.java b/src/java/org/apache/fop/pdf/PDFRoot.java
index 0a0f03d6d..66e58c5f0 100644
--- a/src/java/org/apache/fop/pdf/PDFRoot.java
+++ b/src/java/org/apache/fop/pdf/PDFRoot.java
@@ -52,6 +52,8 @@ public class PDFRoot extends PDFDictionary {
private final PDFDocument document;
+ private PDFDPartRoot dPartRoot;
+
private static final PDFName[] PAGEMODE_NAMES = new PDFName[] {
new PDFName("UseNone"),
@@ -318,4 +320,12 @@ public class PDFRoot extends PDFDictionary {
public PDFDictionary getMarkInfo() {
return (PDFDictionary)get("MarkInfo");
}
+
+ public PDFDPartRoot getDPartRoot() {
+ if (dPartRoot == null) {
+ dPartRoot = getDocument().getFactory().makeDPartRoot();
+ put("DPartRoot", dPartRoot.makeReference());
+ }
+ return dPartRoot;
+ }
}
diff --git a/src/java/org/apache/fop/pdf/PDFVTMode.java b/src/java/org/apache/fop/pdf/PDFVTMode.java
new file mode 100644
index 000000000..0dbb65873
--- /dev/null
+++ b/src/java/org/apache/fop/pdf/PDFVTMode.java
@@ -0,0 +1,45 @@
+/*
+ * 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;
+
+public enum PDFVTMode {
+ DISABLED("PDF/VT disabled"),
+ PDFVT_1("PDF/VT-1");
+
+ private String name;
+
+ PDFVTMode(String s) {
+ name = s;
+ }
+
+ /**
+ * Returns the mode enum object given a String.
+ *
+ * @param s the string
+ * @return the PDFVTMode enum object (DISABLED will be returned if no match is found)
+ */
+ public static PDFVTMode getValueOf(String s) {
+ for (PDFVTMode mode : values()) {
+ if (mode.name.equalsIgnoreCase(s)) {
+ return mode;
+ }
+ }
+ return DISABLED;
+ }
+}
diff --git a/src/java/org/apache/fop/pdf/PDFXMode.java b/src/java/org/apache/fop/pdf/PDFXMode.java
index be0312891..84e7f785a 100644
--- a/src/java/org/apache/fop/pdf/PDFXMode.java
+++ b/src/java/org/apache/fop/pdf/PDFXMode.java
@@ -25,7 +25,8 @@ public enum PDFXMode {
/** PDF/X disabled */
DISABLED("PDF/X disabled"),
/** PDF/X-3:2003 enabled */
- PDFX_3_2003("PDF/X-3:2003");
+ PDFX_3_2003("PDF/X-3:2003"),
+ PDFX_4("PDF/X-4");
private String name;
@@ -48,11 +49,12 @@ public enum PDFXMode {
* @return the PDFAMode enum object (DISABLED will be returned if no match is found)
*/
public static PDFXMode getValueOf(String s) {
- if (PDFX_3_2003.getName().equalsIgnoreCase(s)) {
- return PDFX_3_2003;
- } else {
- return DISABLED;
+ for (PDFXMode mode : values()) {
+ if (mode.name.equalsIgnoreCase(s)) {
+ return mode;
+ }
}
+ return DISABLED;
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java b/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java
index 05e9cb580..e5896b803 100644
--- a/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java
+++ b/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java
@@ -243,6 +243,9 @@ public class PDFDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
toPDFCoordSystem(cropBox, boxTransform),
toPDFCoordSystem(bleedBox, boxTransform),
toPDFCoordSystem(trimBox, boxTransform));
+ if (pdfDoc.getProfile().isPDFVTActive()) {
+ pdfDoc.getFactory().makeDPart(currentPage, pageMasterName);
+ }
if (accessEnabled) {
logicalStructureHandler.startPage(currentPage);
}
diff --git a/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java b/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java
index f25872c4c..bbfb8a9b3 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java
@@ -60,6 +60,7 @@ import static org.apache.fop.render.pdf.PDFRendererOption.LINEARIZATION;
import static org.apache.fop.render.pdf.PDFRendererOption.MERGE_FONTS;
import static org.apache.fop.render.pdf.PDFRendererOption.OUTPUT_PROFILE;
import static org.apache.fop.render.pdf.PDFRendererOption.PDF_A_MODE;
+import static org.apache.fop.render.pdf.PDFRendererOption.PDF_VT_MODE;
import static org.apache.fop.render.pdf.PDFRendererOption.PDF_X_MODE;
import static org.apache.fop.render.pdf.PDFRendererOption.VERSION;
@@ -134,6 +135,7 @@ public final class PDFRendererConfig implements RendererConfig {
buildFilterMapFromConfiguration(cfg);
parseAndPut(PDF_A_MODE, cfg);
parseAndPut(PDF_X_MODE, cfg);
+ parseAndPut(PDF_VT_MODE, cfg);
configureEncryptionParams(cfg, userAgent, strict);
parseAndPut(OUTPUT_PROFILE, cfg);
parseAndPut(DISABLE_SRGB_COLORSPACE, cfg);
diff --git a/src/java/org/apache/fop/render/pdf/PDFRendererOption.java b/src/java/org/apache/fop/render/pdf/PDFRendererOption.java
index cfad76b81..8874f566d 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRendererOption.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRendererOption.java
@@ -24,6 +24,7 @@ import java.net.URISyntaxException;
import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.pdf.PDFAMode;
+import org.apache.fop.pdf.PDFVTMode;
import org.apache.fop.pdf.PDFXMode;
import org.apache.fop.pdf.Version;
import org.apache.fop.render.RendererConfigOption;
@@ -49,6 +50,13 @@ public enum PDFRendererOption implements RendererConfigOption {
return PDFXMode.getValueOf(value);
}
},
+ /** Rendering Options key for the PDF/VT mode, default: {@link PDFVTMode#DISABLED} */
+ PDF_VT_MODE("pdf-vt-mode", PDFVTMode.DISABLED) {
+ @Override
+ PDFVTMode deserialize(String value) {
+ return PDFVTMode.getValueOf(value);
+ }
+ },
/** PDF version entry: specify the version of the PDF document created, datatype: String */
VERSION("version") {
@Override
diff --git a/src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java b/src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java
index 8124db9f5..e4cf2480b 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java
@@ -26,6 +26,7 @@ import java.util.Map;
import org.apache.fop.pdf.PDFAMode;
import org.apache.fop.pdf.PDFEncryptionParams;
+import org.apache.fop.pdf.PDFVTMode;
import org.apache.fop.pdf.PDFXMode;
import org.apache.fop.pdf.Version;
@@ -35,6 +36,7 @@ import static org.apache.fop.render.pdf.PDFRendererOption.LINEARIZATION;
import static org.apache.fop.render.pdf.PDFRendererOption.MERGE_FONTS;
import static org.apache.fop.render.pdf.PDFRendererOption.OUTPUT_PROFILE;
import static org.apache.fop.render.pdf.PDFRendererOption.PDF_A_MODE;
+import static org.apache.fop.render.pdf.PDFRendererOption.PDF_VT_MODE;
import static org.apache.fop.render.pdf.PDFRendererOption.PDF_X_MODE;
import static org.apache.fop.render.pdf.PDFRendererOption.VERSION;
@@ -107,6 +109,10 @@ public final class PDFRendererOptionsConfig {
return (PDFXMode) properties.get(PDF_X_MODE);
}
+ public PDFVTMode getPDFVTMode() {
+ return (PDFVTMode) properties.get(PDF_VT_MODE);
+ }
+
public PDFEncryptionParams getEncryptionParameters() {
return encryptionConfig;
}
diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java b/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java
index f93628331..e8da29b7d 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java
@@ -27,15 +27,18 @@ import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
+import java.util.Date;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
+import java.util.TimeZone;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil;
+import org.apache.xmlgraphics.util.DateFormatUtil;
import org.apache.xmlgraphics.xmp.Metadata;
import org.apache.xmlgraphics.xmp.schemas.DublinCoreSchema;
import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter;
@@ -162,6 +165,7 @@ class PDFRenderingUtil {
private void updatePDFProfiles() {
pdfDoc.getProfile().setPDFAMode(rendererConfig.getPDFAMode());
pdfDoc.getProfile().setPDFXMode(rendererConfig.getPDFXMode());
+ pdfDoc.getProfile().setPDFVTMode(rendererConfig.getPDFVTMode());
}
private void addsRGBColorSpace() throws IOException {
@@ -466,6 +470,18 @@ class PDFRenderingUtil {
for (PDFCollectionEntryExtension entry : extension.getEntries()) {
info.put(entry.getKey(), entry.getValueAsString());
}
+ } else if (type == PDFDictionaryType.VT) {
+ if (currentPage.get("DPart") != null) {
+ augmentDictionary((PDFDictionary)currentPage.get("DPart"), extension);
+ }
+ } else if (type == PDFDictionaryType.PagePiece) {
+ String date = DateFormatUtil.formatPDFDate(new Date(), TimeZone.getDefault());
+ if (currentPage.get("PieceInfo") == null) {
+ currentPage.put("PieceInfo", new PDFDictionary());
+ currentPage.put("LastModified", date);
+ }
+ PDFDictionary d = augmentDictionary((PDFDictionary)currentPage.get("PieceInfo"), extension);
+ d.put("LastModified", date);
} else {
throw new IllegalStateException();
}
@@ -474,8 +490,20 @@ class PDFRenderingUtil {
private PDFDictionary augmentDictionary(PDFDictionary dictionary, PDFDictionaryExtension extension) {
for (PDFCollectionEntryExtension entry : extension.getEntries()) {
if (entry instanceof PDFDictionaryExtension) {
- dictionary.put(entry.getKey(),
- augmentDictionary(new PDFDictionary(dictionary), (PDFDictionaryExtension) entry));
+ String[] keys = entry.getKey().split("/");
+ for (int i = 0; i < keys.length; i++) {
+ if (keys[i].isEmpty()) {
+ throw new IllegalStateException("pdf:dictionary key: " + entry.getKey() + " not valid");
+ }
+ if (i == keys.length - 1) {
+ dictionary.put(keys[i],
+ augmentDictionary(new PDFDictionary(dictionary), (PDFDictionaryExtension) entry));
+ } else {
+ PDFDictionary d = new PDFDictionary();
+ dictionary.put(keys[i], d);
+ dictionary = d;
+ }
+ }
} else if (entry instanceof PDFArrayExtension) {
dictionary.put(entry.getKey(), augmentArray(new PDFArray(dictionary), (PDFArrayExtension) entry));
} else {
diff --git a/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryElement.java b/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryElement.java
index 26b03d5bc..3da224290 100644
--- a/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryElement.java
+++ b/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryElement.java
@@ -107,6 +107,10 @@ public class PDFDictionaryElement extends PDFCollectionEntryElement {
// handled in PDFPageElement subclass
} else if (localName.equals("info")) {
// handled in PDFDocumentInformationElement subclass
+ } else if (localName.equals("vt")) {
+ // handled in PDFVTElement subclass
+ } else if (localName.equals("pagepiece")) {
+ // handled in PDFPagePieceElement subclass
} else if (localName.equals("dictionary")) {
if (!PDFDictionaryType.hasValueOfElementName(parent.getLocalName()) && !PDFObjectType.Array.elementName().equals(parent.getLocalName())) {
invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(), null);
diff --git a/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryExtension.java b/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryExtension.java
index 50b6f3a83..d1367413e 100644
--- a/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryExtension.java
+++ b/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryExtension.java
@@ -71,7 +71,7 @@ public class PDFDictionaryExtension extends PDFCollectionExtension {
@Override
public void addEntry(PDFCollectionEntryExtension entry) {
if ((entry.getKey() == null) || (entry.getKey().length() == 0)) {
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("pdf:dictionary key is empty");
} else {
entries.add(entry);
}
diff --git a/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryType.java b/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryType.java
index 1a3387aa0..4cefc2bad 100644
--- a/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryType.java
+++ b/src/java/org/apache/fop/render/pdf/extensions/PDFDictionaryType.java
@@ -32,7 +32,9 @@ public enum PDFDictionaryType {
Navigator("navigator", true), // navigation node dictionary element
Page("page"), // page dictionary element
/** Document Information Dictionary */
- Info("info");
+ Info("info"),
+ VT("vt"),
+ PagePiece("pagepiece");
private String elementName;
private boolean usesIDAttribute;
diff --git a/src/java/org/apache/fop/render/pdf/extensions/PDFElementMapping.java b/src/java/org/apache/fop/render/pdf/extensions/PDFElementMapping.java
index 5831b1f2a..836b53656 100644
--- a/src/java/org/apache/fop/render/pdf/extensions/PDFElementMapping.java
+++ b/src/java/org/apache/fop/render/pdf/extensions/PDFElementMapping.java
@@ -67,6 +67,10 @@ public class PDFElementMapping extends ElementMapping {
foObjs.put(PDFObjectType.String.elementName(), new PDFCollectionEntryElementMaker(PDFObjectType.String));
// pdf:info
foObjs.put(PDFDictionaryType.Info.elementName(), new PDFDocumentInformationElementMaker());
+ // pdf:vt
+ foObjs.put(PDFDictionaryType.VT.elementName(), new PDFVTElementMaker());
+ // pdf:pagepiece
+ foObjs.put(PDFDictionaryType.PagePiece.elementName(), new PDFPagePieceElementMaker());
}
}
@@ -140,4 +144,15 @@ public class PDFElementMapping extends ElementMapping {
}
}
+ static class PDFVTElementMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new PDFVTElement(parent);
+ }
+ }
+
+ static class PDFPagePieceElementMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new PDFPagePieceElement(parent);
+ }
+ }
}
diff --git a/src/java/org/apache/fop/render/pdf/extensions/PDFVTElement.java b/src/java/org/apache/fop/render/pdf/extensions/PDFVTElement.java
new file mode 100644
index 000000000..24fb50b6c
--- /dev/null
+++ b/src/java/org/apache/fop/render/pdf/extensions/PDFVTElement.java
@@ -0,0 +1,28 @@
+/*
+ * 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.render.pdf.extensions;
+
+import org.apache.fop.fo.FONode;
+
+public class PDFVTElement extends PDFDictionaryElement {
+
+ PDFVTElement(FONode parent) {
+ super(parent, PDFDictionaryType.VT);
+ }
+}
diff --git a/test/java/org/apache/fop/pdf/PDFLinearizationTestCase.java b/test/java/org/apache/fop/pdf/PDFLinearizationTestCase.java
index 7b78c1f5b..3df497e0f 100644
--- a/test/java/org/apache/fop/pdf/PDFLinearizationTestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFLinearizationTestCase.java
@@ -288,7 +288,7 @@ public class PDFLinearizationTestCase {
}
}
- private Map<String, StringBuilder> readObjs(InputStream inputStream) throws IOException {
+ public static Map<String, StringBuilder> readObjs(InputStream inputStream) throws IOException {
Map<String, StringBuilder> objs = new LinkedHashMap<String, StringBuilder>();
StringBuilder sb = new StringBuilder();
String key = null;
diff --git a/test/java/org/apache/fop/pdf/PDFPagePieceTestCase.java b/test/java/org/apache/fop/pdf/PDFPagePieceTestCase.java
new file mode 100644
index 000000000..4ee98b665
--- /dev/null
+++ b/test/java/org/apache/fop/pdf/PDFPagePieceTestCase.java
@@ -0,0 +1,67 @@
+/*
+ * 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;
+
+import java.awt.Dimension;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.util.Arrays;
+
+import javax.xml.transform.stream.StreamResult;
+
+import org.junit.Test;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.FopFactory;
+import org.apache.fop.render.intermediate.IFContext;
+import org.apache.fop.render.intermediate.IFException;
+import org.apache.fop.render.pdf.PDFDocumentHandler;
+import org.apache.fop.render.pdf.extensions.PDFCollectionEntryExtension;
+import org.apache.fop.render.pdf.extensions.PDFDictionaryAttachment;
+import org.apache.fop.render.pdf.extensions.PDFDictionaryExtension;
+import org.apache.fop.render.pdf.extensions.PDFDictionaryType;
+
+import junit.framework.Assert;
+
+public class PDFPagePieceTestCase {
+ @Test
+ public void testPDF() throws IFException {
+ FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
+ FOUserAgent userAgent = fopFactory.newFOUserAgent();
+ PDFDocumentHandler documentHandler = new PDFDocumentHandler(new IFContext(userAgent));
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ documentHandler.setResult(new StreamResult(bos));
+ documentHandler.startDocument();
+ documentHandler.startPage(0, "", "", new Dimension());
+
+ PDFDictionaryExtension dictionaryExtension = mock(PDFDictionaryExtension.class);
+ when(dictionaryExtension.getDictionaryType()).thenReturn(PDFDictionaryType.PagePiece);
+
+ PDFDictionaryExtension child = mock(PDFDictionaryExtension.class);
+ when(child.getKey()).thenReturn("a");
+ when(dictionaryExtension.getEntries()).thenReturn(Arrays.<PDFCollectionEntryExtension>asList(child));
+ documentHandler.handleExtensionObject(new PDFDictionaryAttachment(dictionaryExtension));
+
+ documentHandler.endPage();
+ Assert.assertTrue(bos.toString(), bos.toString().contains("/PieceInfo << /a << >> /LastModified (D:"));
+ }
+}
diff --git a/test/java/org/apache/fop/pdf/PDFVT.fo b/test/java/org/apache/fop/pdf/PDFVT.fo
new file mode 100644
index 000000000..6919afcf6
--- /dev/null
+++ b/test/java/org/apache/fop/pdf/PDFVT.fo
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-family="Arial" xmlns:pdf="http://xmlgraphics.apache.org/fop/extensions/pdf">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="simple" page-height="27.9cm" page-width="21.6cm">
+ <fo:region-body />
+ <pdf:vt>
+ <pdf:dictionary key="DPM/CIP4_Root/CIP4_Production/CIP4_Part">
+ <pdf:string key="CIP4_ProductType">frontpages</pdf:string>
+ </pdf:dictionary>
+ </pdf:vt>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:declarations>
+ <x:xmpmeta xmlns:x="adobe:ns:meta/">
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <dc:title>Document title</dc:title>
+ <dc:creator>Document author</dc:creator>
+ <dc:description>Document subject</dc:description>
+ </rdf:Description>
+ </rdf:RDF>
+ </x:xmpmeta>
+ </fo:declarations>
+ <fo:page-sequence format="1" id="th_default_sequence1" master-reference="simple">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>page 1</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+</fo:root>
diff --git a/test/java/org/apache/fop/pdf/PDFVT.xconf b/test/java/org/apache/fop/pdf/PDFVT.xconf
new file mode 100644
index 000000000..52588f0b0
--- /dev/null
+++ b/test/java/org/apache/fop/pdf/PDFVT.xconf
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<fop version="1.0">
+ <renderers>
+ <renderer mime="application/pdf">
+ <pdf-x-mode>PDF/X-4</pdf-x-mode>
+ <pdf-vt-mode>PDF/VT-1</pdf-vt-mode>
+ <output-profile>test/resources/color/ISOcoated_v2_300_bas.icc</output-profile>
+ <fonts>
+ <font kerning="yes" embed-url="test/resources/fonts/ttf/DejaVuLGCSerif.ttf">
+ <font-triplet name="Arial" style="normal" weight="normal"/>
+ </font>
+ </fonts>
+ </renderer>
+ </renderers>
+</fop>
diff --git a/test/java/org/apache/fop/pdf/PDFVTTestCase.java b/test/java/org/apache/fop/pdf/PDFVTTestCase.java
new file mode 100644
index 000000000..e3dcf2cf6
--- /dev/null
+++ b/test/java/org/apache/fop/pdf/PDFVTTestCase.java
@@ -0,0 +1,142 @@
+/*
+ * 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;
+
+import java.awt.geom.Rectangle2D;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.xml.sax.SAXException;
+
+import org.apache.xmlgraphics.util.QName;
+import org.apache.xmlgraphics.xmp.Metadata;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.Fop;
+import org.apache.fop.apps.FopFactory;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.render.pdf.PDFContentGenerator;
+
+public class PDFVTTestCase {
+ @Test
+ public void testXMP() throws IOException {
+ PDFDocument doc = new PDFDocument("");
+ doc.getProfile().setPDFXMode(PDFXMode.PDFX_4);
+ doc.getProfile().setPDFVTMode(PDFVTMode.PDFVT_1);
+ Metadata metadata = PDFMetadata.createXMPFromPDFDocument(doc);
+ StringBuilder sb = new StringBuilder();
+ Iterator i = metadata.iterator();
+ while (i.hasNext()) {
+ QName k = (QName) i.next();
+ sb.append(k + ": " + metadata.getProperty(k).getValue() + "\n");
+ }
+ String s = sb.toString();
+ Assert.assertTrue(s.contains("pdfxid:GTS_PDFXVersion: PDF/X-4"));
+ Assert.assertTrue(s.contains("xmpMM:VersionID: 1"));
+ Assert.assertTrue(s.contains("pdf:Trapped: False"));
+ Assert.assertTrue(s.contains("xmpMM:RenditionClass: default"));
+ Assert.assertTrue(s.contains("pdf:PDFVersion: 1.4"));
+ Assert.assertTrue(s.contains("pdfvtid:GTS_PDFVTVersion: PDF/VT-1"));
+ }
+
+ @Test
+ public void testPDF() throws IOException {
+ PDFDocument doc = new PDFDocument("");
+ doc.getInfo().setTitle("title");
+ doc.getProfile().setPDFXMode(PDFXMode.PDFX_4);
+ doc.getProfile().setPDFVTMode(PDFVTMode.PDFVT_1);
+ PDFResources resources = new PDFResources(doc);
+ doc.addObject(resources);
+ PDFResourceContext context = new PDFResourceContext(resources);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ PDFContentGenerator gen = new PDFContentGenerator(doc, out, context);
+ Rectangle2D.Float f = new Rectangle2D.Float();
+ PDFPage page = new PDFPage(resources, 0, f, f, f, f);
+ doc.addImage(context, new BitmapImage("", 1, 1, new byte[0], null));
+ doc.registerObject(page);
+ doc.getFactory().makeDPart(page, "master");
+ gen.flushPDFDoc();
+ doc.outputTrailer(out);
+
+ Collection<StringBuilder> objs = PDFLinearizationTestCase.readObjs(
+ new ByteArrayInputStream(out.toByteArray())).values();
+ Assert.assertTrue(getObj(objs, "/Type /Catalog").contains("/DPartRoot "));
+ Assert.assertTrue(getObj(objs, "/Type /DPartRoot").contains("/NodeNameList [/root /record]"));
+ Assert.assertTrue(
+ getObj(objs, "/Subtype /Image").contains("/GTS_XID (uuid:d41d8cd9-8f00-3204-a980-0998ecf8427e)"));
+ }
+
+ @Test
+ public void textFO() throws IOException, SAXException, TransformerException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI(),
+ new FileInputStream("test/java/org/apache/fop/pdf/PDFVT.xconf"));
+ FOUserAgent userAgent = fopFactory.newFOUserAgent();
+
+ Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent, out);
+ Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ Source src = new StreamSource(new FileInputStream("test/java/org/apache/fop/pdf/PDFVT.fo"));
+ Result res = new SAXResult(fop.getDefaultHandler());
+ transformer.transform(src, res);
+
+ Map<String, StringBuilder> objs =
+ PDFLinearizationTestCase.readObjs(new ByteArrayInputStream(out.toByteArray()));
+ String dpart = getObj(objs.values(), "/DParts");
+ int v = getValue("/DParts", dpart);
+ String dpm = objs.get(v + " 0 obj").toString();
+ Assert.assertTrue(dpm.contains(
+ "/DPM << /CIP4_Root << /CIP4_Production << /CIP4_Part << /CIP4_ProductType (frontpages) >>"));
+ }
+
+ private int getValue(String name, String firstObj) throws IOException {
+ String[] split = firstObj.split(" ");
+ for (int i = 0; i < split.length; i++) {
+ if (split[i].equals(name)) {
+ return Integer.valueOf(split[i + 1].replace("[[", ""));
+ }
+ }
+ throw new IOException(name + " not found " + firstObj);
+ }
+
+ private String getObj(Collection<StringBuilder> objs, String x) {
+ for (StringBuilder s : objs) {
+ if (s.toString().contains(x)) {
+ return s.toString();
+ }
+ }
+ return null;
+ }
+}
diff --git a/test/resources/color/ISOcoated_v2_300_bas.icc b/test/resources/color/ISOcoated_v2_300_bas.icc
new file mode 100644
index 000000000..71faa91f9
--- /dev/null
+++ b/test/resources/color/ISOcoated_v2_300_bas.icc
Binary files differ