aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Hennebert <vhennebert@apache.org>2012-11-19 18:53:11 +0000
committerVincent Hennebert <vhennebert@apache.org>2012-11-19 18:53:11 +0000
commit638ea00309ef225858fdc2b5ab2889e1236d783d (patch)
tree2d10d41ef1459a40e0a3ee644e08a21a412dd823
parentff6508e118c14d1e8eb270a559d147e85bf0418f (diff)
downloadxmlgraphics-fop-638ea00309ef225858fdc2b5ab2889e1236d783d.tar.gz
xmlgraphics-fop-638ea00309ef225858fdc2b5ab2889e1236d783d.zip
Bugzilla #54169: Split the parent tree (the number tree corresponding to the ParentTree entry in the structure tree root) to avoid reaching the internal limits of Acrobat Pro, that would otherwise split it at the wrong place when saving the document.
Patch submitted by Robert Meyer git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1411352 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/java/org/apache/fop/pdf/PDFNumberTreeNode.java28
-rw-r--r--src/java/org/apache/fop/pdf/PDFPageLabels.java14
-rw-r--r--src/java/org/apache/fop/pdf/PDFParentTree.java46
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java4
-rw-r--r--status.xml5
-rw-r--r--test/java/org/apache/fop/pdf/PDFParentTreeTestCase.java107
-rw-r--r--test/pdf/1.5/test.pdfbin92694 -> 94625 bytes
-rw-r--r--test/pdf/accessibility/pdf/background-image_jpg_repeat.pdfbin12760 -> 12832 bytes
-rw-r--r--test/pdf/accessibility/pdf/background-image_jpg_single.pdfbin12599 -> 12671 bytes
-rw-r--r--test/pdf/accessibility/pdf/background-image_png_repeat.pdfbin35383 -> 35455 bytes
-rw-r--r--test/pdf/accessibility/pdf/background-image_png_single.pdfbin58594 -> 58666 bytes
-rw-r--r--test/pdf/accessibility/pdf/background-image_svg_repeat.pdfbin17086 -> 17158 bytes
-rw-r--r--test/pdf/accessibility/pdf/background-image_svg_single.pdfbin9898 -> 9970 bytes
-rw-r--r--test/pdf/accessibility/pdf/complete.pdfbin96564 -> 96638 bytes
-rw-r--r--test/pdf/accessibility/pdf/hyphenation.pdfbin8251 -> 8323 bytes
-rw-r--r--test/pdf/accessibility/pdf/image_jpg.pdfbin8977 -> 9049 bytes
-rw-r--r--test/pdf/accessibility/pdf/image_png.pdfbin58018 -> 58090 bytes
-rw-r--r--test/pdf/accessibility/pdf/image_svg.pdfbin14233 -> 14305 bytes
-rw-r--r--test/pdf/accessibility/pdf/image_wmf.pdfbin248058 -> 248130 bytes
-rw-r--r--test/pdf/accessibility/pdf/language.pdfbin8717 -> 8789 bytes
-rw-r--r--test/pdf/accessibility/pdf/leader.pdfbin9278 -> 9350 bytes
-rw-r--r--test/pdf/accessibility/pdf/links.pdfbin9511 -> 9583 bytes
-rw-r--r--test/pdf/accessibility/pdf/role.pdfbin18986 -> 19058 bytes
-rw-r--r--test/pdf/accessibility/pdf/role_non-standard.pdfbin18677 -> 18749 bytes
-rw-r--r--test/pdf/accessibility/pdf/side-regions.pdfbin28067 -> 28141 bytes
-rw-r--r--test/pdf/accessibility/pdf/table_row-col-span.pdfbin19354 -> 19428 bytes
-rw-r--r--test/pdf/accessibility/pdf/text_1.pdfbin7423 -> 7495 bytes
-rw-r--r--test/pdf/accessibility/pdf/text_2.pdfbin10364 -> 10436 bytes
-rw-r--r--test/pdf/accessibility/pdf/text_font-embedding.pdfbin28477 -> 28549 bytes
-rw-r--r--test/pdf/accessibility/pdf/th_scope.pdfbin16293 -> 16365 bytes
30 files changed, 173 insertions, 31 deletions
diff --git a/src/java/org/apache/fop/pdf/PDFNumberTreeNode.java b/src/java/org/apache/fop/pdf/PDFNumberTreeNode.java
index 72fbcd1c6..599530439 100644
--- a/src/java/org/apache/fop/pdf/PDFNumberTreeNode.java
+++ b/src/java/org/apache/fop/pdf/PDFNumberTreeNode.java
@@ -49,7 +49,7 @@ public class PDFNumberTreeNode extends PDFDictionary {
* @return the Kids array
*/
public PDFArray getKids() {
- return (PDFArray)get(KIDS);
+ return (PDFArray) get(KIDS);
}
/**
@@ -65,7 +65,12 @@ public class PDFNumberTreeNode extends PDFDictionary {
* @return the Nums array
*/
public PDFNumsArray getNums() {
- return (PDFNumsArray)get(NUMS);
+ PDFNumsArray nums = (PDFNumsArray) get(NUMS);
+ if (nums == null) {
+ nums = new PDFNumsArray(this);
+ setNums(nums);
+ }
+ return nums;
}
/**
@@ -83,7 +88,7 @@ public class PDFNumberTreeNode extends PDFDictionary {
*/
public Integer getLowerLimit() {
PDFArray limits = prepareLimitsArray();
- return (Integer)limits.get(0);
+ return (Integer) limits.get(0);
}
/**
@@ -101,12 +106,25 @@ public class PDFNumberTreeNode extends PDFDictionary {
*/
public Integer getUpperLimit() {
PDFArray limits = prepareLimitsArray();
- return (Integer)limits.get(1);
+ return (Integer) limits.get(1);
+ }
+
+ /**
+ * Adds a number and object to the nums array and increases the
+ * upper limit should it be required.
+ * @param num The unique number identifying the object in the array
+ * @param object The object being added
+ */
+ protected void addToNums(int num, Object object) {
+ getNums().put(num, object);
+ if (getUpperLimit() < num) {
+ setUpperLimit(num);
+ }
}
private PDFArray prepareLimitsArray() {
- PDFArray limits = (PDFArray)get(LIMITS);
+ PDFArray limits = (PDFArray) get(LIMITS);
if (limits == null) {
limits = new PDFArray(this, new Object[2]);
put(LIMITS, limits);
diff --git a/src/java/org/apache/fop/pdf/PDFPageLabels.java b/src/java/org/apache/fop/pdf/PDFPageLabels.java
index e95c97a25..e7b90ec4e 100644
--- a/src/java/org/apache/fop/pdf/PDFPageLabels.java
+++ b/src/java/org/apache/fop/pdf/PDFPageLabels.java
@@ -57,20 +57,6 @@ public class PDFPageLabels extends PDFNumberTreeNode {
}
/**
- * Returns the Nums object
- * @return the Nums object (an empty PDFNumsArray for the "/Nums" entry is created
- * if it doesn't exist)
- */
- public PDFNumsArray getNums() {
- PDFNumsArray nums = super.getNums();
- if (nums == null) {
- nums = new PDFNumsArray(this);
- setNums(nums);
- }
- return nums;
- }
-
- /**
* Adds a new entry, if necessary, to the /PageLabels dictionary.
* @param index the page index (0 for page 1)
* @param pageLabel the page number as a string
diff --git a/src/java/org/apache/fop/pdf/PDFParentTree.java b/src/java/org/apache/fop/pdf/PDFParentTree.java
index 7876bbc0c..e03545568 100644
--- a/src/java/org/apache/fop/pdf/PDFParentTree.java
+++ b/src/java/org/apache/fop/pdf/PDFParentTree.java
@@ -24,18 +24,44 @@ package org.apache.fop.pdf;
*/
public class PDFParentTree extends PDFNumberTreeNode {
+ private static final int MAX_NUMS_ARRAY_SIZE = 50;
+
+ public PDFParentTree() {
+ put("Kids", new PDFArray());
+ }
+
+ @Override
+ public void addToNums(int num, Object object) {
+ int arrayIndex = num / MAX_NUMS_ARRAY_SIZE;
+ setNumOfKidsArrays(arrayIndex + 1);
+ insertItemToNumsArray(arrayIndex, num, object);
+ }
+
+ private void setNumOfKidsArrays(int numKids) {
+ for (int i = getKids().length(); i < numKids; i++) {
+ PDFNumberTreeNode newArray = new PDFNumberTreeNode();
+ newArray.setNums(new PDFNumsArray(newArray));
+ newArray.setLowerLimit(i * MAX_NUMS_ARRAY_SIZE);
+ newArray.setUpperLimit(i * MAX_NUMS_ARRAY_SIZE);
+ addKid(newArray);
+ }
+ }
+
/**
- * Returns the number tree corresponding to this parent tree.
- *
- * @return the number tree
+ * Registers a child object and adds it to the Kids array.
+ * @param kid The child PDF object to be added
*/
- public PDFNumsArray getNums() {
- PDFNumsArray nums = super.getNums();
- if (nums == null) {
- nums = new PDFNumsArray(this);
- setNums(nums);
- }
- return nums;
+ private void addKid(PDFObject kid) {
+ assert getDocument() != null;
+ getDocument().assignObjectNumber(kid);
+ getDocument().addTrailerObject(kid);
+ ((PDFArray) get("Kids")).add(kid);
+ }
+
+ private void insertItemToNumsArray(int array, int num, Object object) {
+ assert getKids().get(array) instanceof PDFNumberTreeNode;
+ PDFNumberTreeNode numsArray = (PDFNumberTreeNode) getKids().get(array);
+ numsArray.addToNums(num, object);
}
}
diff --git a/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java b/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java
index ee00d2401..c532a05a4 100644
--- a/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java
+++ b/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java
@@ -124,7 +124,7 @@ class PDFLogicalStructureHandler {
// being output to the PDF.
// This should really be handled by PDFNumsArray
pdfDoc.registerObject(pageParentTreeArray);
- parentTree.getNums().put(currentPage.getStructParents(), pageParentTreeArray);
+ parentTree.addToNums(currentPage.getStructParents(), pageParentTreeArray);
}
private MarkedContentInfo addToParentTree(PDFStructElem structureTreeElement) {
@@ -198,7 +198,7 @@ class PDFLogicalStructureHandler {
contentItem.put("Type", OBJR);
contentItem.put("Pg", this.currentPage);
contentItem.put("Obj", link);
- parentTree.getNums().put(structParent, structureTreeElement);
+ parentTree.addToNums(structParent, structureTreeElement);
structureTreeElement.addKid(contentItem);
}
diff --git a/status.xml b/status.xml
index 990a15f5e..9362983b2 100644
--- a/status.xml
+++ b/status.xml
@@ -59,6 +59,11 @@
documents. Example: the fix of marks layering will be such a case when it's done.
-->
<release version="FOP Trunk" date="TBD">
+ <action context="Renderers" dev="VH" type="fix" fixes-bug="54169" due-to="Robert Meyer">
+ Split the parent tree (the number tree corresponding to the ParentTree entry in the
+ structure tree root) to avoid reaching the internal limits of Acrobat Pro, that would
+ otherwise split it at the wrong place when saving the document.
+ </action>
<action context="Fonts" dev="MH" type="add" fixes-bug="54120">
Created a simple mechanism to avoid NPEs when AWT fonts are requested from Batik
for AFP output.
diff --git a/test/java/org/apache/fop/pdf/PDFParentTreeTestCase.java b/test/java/org/apache/fop/pdf/PDFParentTreeTestCase.java
new file mode 100644
index 000000000..6fa5d6a42
--- /dev/null
+++ b/test/java/org/apache/fop/pdf/PDFParentTreeTestCase.java
@@ -0,0 +1,107 @@
+/*
+ * 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 org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Tests that the nums array in the ParentTree dictionary is correctly being split into
+ * separate arrays if the elements number exceeds the set limit.
+ */
+public class PDFParentTreeTestCase {
+
+ private PDFParentTree parentTree;
+
+ @Before
+ public void initializeStructureTree() {
+ parentTree = new PDFParentTree();
+ PDFDocument pdfDocument = new PDFDocument("test");
+ pdfDocument.makeStructTreeRoot(parentTree);
+ }
+
+ /**
+ * Adds less structured items than the imposed limit which should result
+ * in only one nums array being created.
+ * @throws Exception
+ */
+ @Test
+ public void testNoSplit() throws Exception {
+ assertEquals(getArrayNumber(45), 1);
+ }
+
+ /**
+ * Adds more than the imposed array limit to test that it splits the
+ * nums array into two objects.
+ * @throws Exception
+ */
+ @Test
+ public void testSingleSplit() throws Exception {
+ assertEquals(getArrayNumber(70), 2);
+ }
+
+ /**
+ * Adds items to the nums array to cause and test that multiple splits occur
+ * @throws Exception
+ */
+ @Test
+ public void testMultipleSplit() throws Exception {
+ assertEquals(getArrayNumber(165), 4);
+ }
+
+ /**
+ * Ensures that items added out of order get added to the correct nums array
+ * @throws Exception
+ */
+ @Test
+ public void testOutOfOrderSplit() throws Exception {
+ PDFStructElem structElem = mock(PDFStructElem.class);
+ for (int num = 50; num < 53; num++) {
+ parentTree.addToNums(num, structElem);
+ }
+ assertEquals(getArrayNumber(50), 2);
+ PDFNumberTreeNode treeNode = (PDFNumberTreeNode) parentTree.getKids().get(0);
+ for (int num = 0; num < 50; num++) {
+ assertTrue(treeNode.getNums().map.containsKey(num));
+ }
+ treeNode = (PDFNumberTreeNode) parentTree.getKids().get(1);
+ for (int num = 50; num < 53; num++) {
+ assertTrue(treeNode.getNums().map.containsKey(num));
+ }
+ }
+
+ /**
+ * Gets the number of arrays created for a given number of elements
+ * @param elementNumber The number of elements to be added to the nums array
+ * @return Returns the number of array objects
+ * @throws Exception
+ */
+ private int getArrayNumber(int elementNumber) throws Exception {
+ PDFStructElem structElem = mock(PDFStructElem.class);
+ for (int structParent = 0; structParent < elementNumber; structParent++) {
+ parentTree.addToNums(structParent, structElem);
+ }
+ return parentTree.getKids().length();
+ }
+}
diff --git a/test/pdf/1.5/test.pdf b/test/pdf/1.5/test.pdf
index d97648e1e..e937afd58 100644
--- a/test/pdf/1.5/test.pdf
+++ b/test/pdf/1.5/test.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/background-image_jpg_repeat.pdf b/test/pdf/accessibility/pdf/background-image_jpg_repeat.pdf
index 65f04cdef..4c2fe4687 100644
--- a/test/pdf/accessibility/pdf/background-image_jpg_repeat.pdf
+++ b/test/pdf/accessibility/pdf/background-image_jpg_repeat.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/background-image_jpg_single.pdf b/test/pdf/accessibility/pdf/background-image_jpg_single.pdf
index 6803ba999..74b17c337 100644
--- a/test/pdf/accessibility/pdf/background-image_jpg_single.pdf
+++ b/test/pdf/accessibility/pdf/background-image_jpg_single.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/background-image_png_repeat.pdf b/test/pdf/accessibility/pdf/background-image_png_repeat.pdf
index d42d935aa..f69e373bc 100644
--- a/test/pdf/accessibility/pdf/background-image_png_repeat.pdf
+++ b/test/pdf/accessibility/pdf/background-image_png_repeat.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/background-image_png_single.pdf b/test/pdf/accessibility/pdf/background-image_png_single.pdf
index ba39a2b31..cdba6192e 100644
--- a/test/pdf/accessibility/pdf/background-image_png_single.pdf
+++ b/test/pdf/accessibility/pdf/background-image_png_single.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/background-image_svg_repeat.pdf b/test/pdf/accessibility/pdf/background-image_svg_repeat.pdf
index 1de4c98a1..ed74244b3 100644
--- a/test/pdf/accessibility/pdf/background-image_svg_repeat.pdf
+++ b/test/pdf/accessibility/pdf/background-image_svg_repeat.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/background-image_svg_single.pdf b/test/pdf/accessibility/pdf/background-image_svg_single.pdf
index b89ea182a..d2245e349 100644
--- a/test/pdf/accessibility/pdf/background-image_svg_single.pdf
+++ b/test/pdf/accessibility/pdf/background-image_svg_single.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/complete.pdf b/test/pdf/accessibility/pdf/complete.pdf
index 9b4df8c40..844106f23 100644
--- a/test/pdf/accessibility/pdf/complete.pdf
+++ b/test/pdf/accessibility/pdf/complete.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/hyphenation.pdf b/test/pdf/accessibility/pdf/hyphenation.pdf
index d8552f63a..401fbf356 100644
--- a/test/pdf/accessibility/pdf/hyphenation.pdf
+++ b/test/pdf/accessibility/pdf/hyphenation.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/image_jpg.pdf b/test/pdf/accessibility/pdf/image_jpg.pdf
index e35768d8a..76f5509c8 100644
--- a/test/pdf/accessibility/pdf/image_jpg.pdf
+++ b/test/pdf/accessibility/pdf/image_jpg.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/image_png.pdf b/test/pdf/accessibility/pdf/image_png.pdf
index a33d2ed3f..0a5641aaa 100644
--- a/test/pdf/accessibility/pdf/image_png.pdf
+++ b/test/pdf/accessibility/pdf/image_png.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/image_svg.pdf b/test/pdf/accessibility/pdf/image_svg.pdf
index 1184ddef9..eaf6d56c4 100644
--- a/test/pdf/accessibility/pdf/image_svg.pdf
+++ b/test/pdf/accessibility/pdf/image_svg.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/image_wmf.pdf b/test/pdf/accessibility/pdf/image_wmf.pdf
index 43c15d9ea..819f385a6 100644
--- a/test/pdf/accessibility/pdf/image_wmf.pdf
+++ b/test/pdf/accessibility/pdf/image_wmf.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/language.pdf b/test/pdf/accessibility/pdf/language.pdf
index 48a5f9f52..e32f4f7e9 100644
--- a/test/pdf/accessibility/pdf/language.pdf
+++ b/test/pdf/accessibility/pdf/language.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/leader.pdf b/test/pdf/accessibility/pdf/leader.pdf
index e277699e5..869a47d76 100644
--- a/test/pdf/accessibility/pdf/leader.pdf
+++ b/test/pdf/accessibility/pdf/leader.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/links.pdf b/test/pdf/accessibility/pdf/links.pdf
index 896620bfb..5c63a2574 100644
--- a/test/pdf/accessibility/pdf/links.pdf
+++ b/test/pdf/accessibility/pdf/links.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/role.pdf b/test/pdf/accessibility/pdf/role.pdf
index 6e26032ff..a91e8b983 100644
--- a/test/pdf/accessibility/pdf/role.pdf
+++ b/test/pdf/accessibility/pdf/role.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/role_non-standard.pdf b/test/pdf/accessibility/pdf/role_non-standard.pdf
index edf7541df..c7a55233c 100644
--- a/test/pdf/accessibility/pdf/role_non-standard.pdf
+++ b/test/pdf/accessibility/pdf/role_non-standard.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/side-regions.pdf b/test/pdf/accessibility/pdf/side-regions.pdf
index 22364c2c8..650e962b3 100644
--- a/test/pdf/accessibility/pdf/side-regions.pdf
+++ b/test/pdf/accessibility/pdf/side-regions.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/table_row-col-span.pdf b/test/pdf/accessibility/pdf/table_row-col-span.pdf
index eec14fa3d..9a05c1892 100644
--- a/test/pdf/accessibility/pdf/table_row-col-span.pdf
+++ b/test/pdf/accessibility/pdf/table_row-col-span.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/text_1.pdf b/test/pdf/accessibility/pdf/text_1.pdf
index f3daa44b0..71b32f80c 100644
--- a/test/pdf/accessibility/pdf/text_1.pdf
+++ b/test/pdf/accessibility/pdf/text_1.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/text_2.pdf b/test/pdf/accessibility/pdf/text_2.pdf
index 5a2abcf2f..ac1662659 100644
--- a/test/pdf/accessibility/pdf/text_2.pdf
+++ b/test/pdf/accessibility/pdf/text_2.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/text_font-embedding.pdf b/test/pdf/accessibility/pdf/text_font-embedding.pdf
index e7f75b5a3..d724af9e9 100644
--- a/test/pdf/accessibility/pdf/text_font-embedding.pdf
+++ b/test/pdf/accessibility/pdf/text_font-embedding.pdf
Binary files differ
diff --git a/test/pdf/accessibility/pdf/th_scope.pdf b/test/pdf/accessibility/pdf/th_scope.pdf
index 9d19548d7..68a98987b 100644
--- a/test/pdf/accessibility/pdf/th_scope.pdf
+++ b/test/pdf/accessibility/pdf/th_scope.pdf
Binary files differ