You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by ss...@apache.org on 2015/02/06 17:23:26 UTC
svn commit: r1657884 - in
/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF: lib/ lib/build/
src/java/org/apache/fop/render/pdf/pdfbox/
test/java/org/apache/fop/render/pdf/ test/resources/
Author: ssteiner
Date: Fri Feb 6 16:23:25 2015
New Revision: 1657884
URL: http://svn.apache.org/r1657884
Log:
FOP-2436: Merging of Tagged (Accessible) PDF
Added:
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/mockito-core-1.8.5.LICENCE.txt (with props)
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/mockito-core-1.8.5.NOTICE.txt (with props)
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/mockito-core-1.8.5.jar (with props)
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/objenesis-1.0.0.LICENSE.txt (with props)
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/objenesis-1.0.0.jar (with props)
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/DocumentRootModifier.java (with props)
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PageParentTreeFinder.java (with props)
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/StructureTreeMerger.java (with props)
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/StructureTreeMergerUtil.java (with props)
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/TaggedPDFConductor.java (with props)
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/DocumentRootModifierTestCase.java (with props)
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/PageParentTreeFinderTestCase.java (with props)
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/StructureTreeMergerTestCase.java (with props)
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/TaggedPDFConductorTestCase.java (with props)
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/NoParentTree.pdf (with props)
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/emptyRowTable.pdf (with props)
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/helloWorld.pdf (with props)
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/linkTagged.pdf (with props)
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/otf.pdf (with props)
Modified:
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/fop.jar
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/MergeFontsPDFWriter.java
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxImageHandler.java
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PDFWriter.java
xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/mockito-core-1.8.5.LICENCE.txt
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/mockito-core-1.8.5.LICENCE.txt?rev=1657884&view=auto
==============================================================================
--- xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/mockito-core-1.8.5.LICENCE.txt (added)
+++ xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/mockito-core-1.8.5.LICENCE.txt Fri Feb 6 16:23:25 2015
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2007 Mockito contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/mockito-core-1.8.5.LICENCE.txt
------------------------------------------------------------------------------
svn:eol-style = native
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/mockito-core-1.8.5.NOTICE.txt
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/mockito-core-1.8.5.NOTICE.txt?rev=1657884&view=auto
==============================================================================
--- xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/mockito-core-1.8.5.NOTICE.txt (added)
+++ xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/mockito-core-1.8.5.NOTICE.txt Fri Feb 6 16:23:25 2015
@@ -0,0 +1,11 @@
+Mockito license - MIT.
+
+Libraries used:
+
+Cglib - Apache License 2.0
+ASM - BSD license
+
+Mockito all distribution:
+
+Objenesis - MIT license
+Hamcrest - BSD license
\ No newline at end of file
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/mockito-core-1.8.5.NOTICE.txt
------------------------------------------------------------------------------
svn:eol-style = native
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/mockito-core-1.8.5.jar
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/mockito-core-1.8.5.jar?rev=1657884&view=auto
==============================================================================
Binary file - no diff available.
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/mockito-core-1.8.5.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/objenesis-1.0.0.LICENSE.txt
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/objenesis-1.0.0.LICENSE.txt?rev=1657884&view=auto
==============================================================================
--- xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/objenesis-1.0.0.LICENSE.txt (added)
+++ xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/objenesis-1.0.0.LICENSE.txt Fri Feb 6 16:23:25 2015
@@ -0,0 +1,18 @@
+Copyright (c) 2003-2008, Objenesis Team and all contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/objenesis-1.0.0.LICENSE.txt
------------------------------------------------------------------------------
svn:eol-style = native
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/objenesis-1.0.0.jar
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/objenesis-1.0.0.jar?rev=1657884&view=auto
==============================================================================
Binary file - no diff available.
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/build/objenesis-1.0.0.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Modified: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/fop.jar
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/lib/fop.jar?rev=1657884&r1=1657883&r2=1657884&view=diff
==============================================================================
Binary files - no diff available.
Modified: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java?rev=1657884&r1=1657883&r2=1657884&view=diff
==============================================================================
--- xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java (original)
+++ xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java Fri Feb 6 16:23:25 2015
@@ -40,7 +40,9 @@ import org.apache.fop.pdf.PDFArray;
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFPage;
import org.apache.fop.pdf.PDFResources;
+import org.apache.fop.pdf.PDFStructElem;
import org.apache.fop.pdf.Version;
+import org.apache.fop.render.pdf.PDFLogicalStructureHandler;
import org.apache.fop.render.pdf.pdfbox.Cache.ValueMaker;
/**
@@ -67,8 +69,11 @@ public abstract class AbstractPDFBoxHand
= Collections.synchronizedMap(new WeakHashMap<Object, Cache<String, Map<Object, Object>>>());
protected String createStreamForPDF(ImagePDF image, PDFPage targetPage, FOUserAgent userAgent,
- AffineTransform at, FontInfo fontinfo, Rectangle pos, Map<Integer, PDFArray> pageNumbers)
- throws IOException {
+ AffineTransform at, FontInfo fontinfo, Rectangle pos,
+ Map<Integer, PDFArray> pageNumbers,
+ PDFLogicalStructureHandler handler,
+ PDFStructElem curentSessionElem) throws IOException {
+
EventBroadcaster eventBroadcaster = null;
if (userAgent != null) {
eventBroadcaster = userAgent.getEventBroadcaster();
@@ -117,7 +122,15 @@ public abstract class AbstractPDFBoxHand
}
PDFBoxAdapter adapter = new PDFBoxAdapter(targetPage, objectCache, pageNumbers);
- String stream = adapter.createStreamFromPDFBoxPage(pddoc, page, originalImageUri, at, fontinfo, pos);
+ if (handler != null) {
+ adapter.setCurrentMCID(handler.getPageParentTree().length());
+ }
+ String stream = adapter.createStreamFromPDFBoxPage(pddoc, page, originalImageUri,
+ at, fontinfo, pos);
+ if (userAgent.isAccessibilityEnabled()) {
+ TaggedPDFConductor conductor = new TaggedPDFConductor(curentSessionElem, handler, page, adapter);
+ conductor.handleLogicalStructure(pddoc);
+ }
return stream;
}
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/DocumentRootModifier.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/DocumentRootModifier.java?rev=1657884&view=auto
==============================================================================
--- xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/DocumentRootModifier.java (added)
+++ xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/DocumentRootModifier.java Fri Feb 6 16:23:25 2015
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+package org.apache.fop.render.pdf.pdfbox;
+
+import java.io.IOException;
+
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSName;
+
+import org.apache.fop.pdf.PDFDictionary;
+import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.pdf.PDFStructTreeRoot;
+
+public class DocumentRootModifier {
+
+ private PDFBoxAdapter adapter;
+ private PDFDocument pdfDoc;
+
+ public DocumentRootModifier(PDFBoxAdapter adapter, PDFDocument pdfDoc) {
+ this.adapter = adapter;
+ this.pdfDoc = pdfDoc;
+ }
+
+ public void structTreeRootEntriesToCopy(COSDictionary structRootDict) throws IOException {
+ checkForMap(structRootDict, COSName.ROLE_MAP.getName());
+ checkForMap(structRootDict, "CLASS_MAP");
+ }
+
+ private void checkForMap(COSDictionary structRootDict, String mapName) throws IOException {
+ if (structRootDict.containsKey(mapName)) {
+ COSDictionary addedMapDict = (COSDictionary)structRootDict.getDictionaryObject(mapName);
+ PDFDictionary temp = (PDFDictionary) adapter.cloneForNewDocument(addedMapDict);
+ PDFStructTreeRoot structTreeRoot = pdfDoc.getRoot().getStructTreeRoot();
+ if (!structTreeRoot.containsKey(mapName)) {
+ structTreeRoot.put(mapName, temp);
+ } else {
+ PDFDictionary rootMap = (PDFDictionary)structTreeRoot.get(mapName);
+ addMapToStructTreeRoot(rootMap, temp, mapName);
+ }
+ }
+ }
+
+ private void mergeMapClass(PDFDictionary main, PDFDictionary addition) {
+ for (String key : addition.keySet()) {
+ main.put(key, addition.get(key));
+ }
+ }
+
+ private void mergeRoleMaps(PDFDictionary structRoot, PDFDictionary addition) {
+ for (String key : addition.keySet()) {
+ if (!structRoot.containsKey(key)) {
+ structRoot.put(key, addition.get(key));
+ }
+ }
+ }
+
+ private void addMapToStructTreeRoot(PDFDictionary rootMap, PDFDictionary map, String mapName) {
+ if (mapName.equals(COSName.ROLE_MAP.getName())) {
+ mergeRoleMaps(rootMap, map);
+ } else {
+ mergeMapClass(rootMap, map);
+ }
+ }
+}
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/DocumentRootModifier.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/MergeFontsPDFWriter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/MergeFontsPDFWriter.java?rev=1657884&r1=1657883&r2=1657884&view=diff
==============================================================================
--- xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/MergeFontsPDFWriter.java (original)
+++ xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/MergeFontsPDFWriter.java Fri Feb 6 16:23:25 2015
@@ -68,7 +68,7 @@ public class MergeFontsPDFWriter extends
private Collection<String> parentFonts;
public MergeFontsPDFWriter(COSDictionary fonts, FontInfo fontInfo, String key, List<COSName> resourceNames) {
- super(key, resourceNames);
+ super(key, resourceNames, 0);
this.fonts = fonts;
this.fontInfo = fontInfo;
}
Modified: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java?rev=1657884&r1=1657883&r2=1657884&view=diff
==============================================================================
--- xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java (original)
+++ xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java Fri Feb 6 16:23:25 2015
@@ -100,6 +100,8 @@ public class PDFBoxAdapter {
private Map<COSName, String> newXObj = new HashMap<COSName, String>();
private Map<Integer, PDFArray> pageNumbers;
+ private int currentMCID;
+
/**
* Creates a new PDFBoxAdapter.
* @param targetPage The target FOP PDF page object
@@ -113,15 +115,27 @@ public class PDFBoxAdapter {
this.pageNumbers = pageNumbers;
}
- private Object cloneForNewDocument(Object base) throws IOException {
+ public PDFPage getTargetPage() {
+ return targetPage;
+ }
+
+ public int getCurrentMCID() {
+ return currentMCID;
+ }
+
+ public void setCurrentMCID(int currentMCID) {
+ this.currentMCID = currentMCID;
+ }
+
+ protected Object cloneForNewDocument(Object base) throws IOException {
return cloneForNewDocument(base, base);
}
- private Object cloneForNewDocument(Object base, Object keyBase) throws IOException {
+ protected Object cloneForNewDocument(Object base, Object keyBase) throws IOException {
return cloneForNewDocument(base, keyBase, Collections.EMPTY_LIST);
}
- private Object cloneForNewDocument(Object base, Object keyBase, Collection exclude) throws IOException {
+ protected Object cloneForNewDocument(Object base, Object keyBase, Collection exclude) throws IOException {
if (base == null) {
return null;
}
@@ -262,11 +276,11 @@ public class PDFBoxAdapter {
return cacheClonedObject(keyBase, stream);
}
- private Object getCachedClone(Object base) {
+ protected Object getCachedClone(Object base) {
return clonedVersion.get(getBaseKey(base));
}
- private Object cacheClonedObject(Object base, Object cloned) {
+ protected Object cacheClonedObject(Object base, Object cloned) {
Object key = getBaseKey(base);
if (key == null) {
return cloned;
@@ -276,7 +290,7 @@ public class PDFBoxAdapter {
pdfDoc.registerObject(pdfobj);
if (log.isTraceEnabled()) {
log.trace(key + ": " + pdfobj.getClass().getName() + " registered as "
- + pdfobj.getObjectNumber() + " " + pdfobj.getGeneration());
+ + pdfobj.getObjectNumber() + " " + pdfobj.getGeneration());
}
}
clonedVersion.put(key, cloned);
@@ -292,13 +306,12 @@ public class PDFBoxAdapter {
}
}
- private void transferDict(COSDictionary orgDict, PDFStream targetDict,
- Set filter) throws IOException {
+ private void transferDict(COSDictionary orgDict, PDFStream targetDict, Set filter) throws IOException {
transferDict(orgDict, targetDict, filter, false);
}
- private void transferDict(COSDictionary orgDict, PDFStream targetDict,
- Set filter, boolean inclusive) throws IOException {
+ private void transferDict(COSDictionary orgDict, PDFStream targetDict, Set filter, boolean inclusive)
+ throws IOException {
Set<COSName> keys = orgDict.keySet();
for (COSName key : keys) {
if (inclusive && !filter.contains(key.getName())) {
@@ -354,8 +367,11 @@ public class PDFBoxAdapter {
// }
}
if (newStream == null) {
- newStream = new PDFWriter(uniqueName,
- getResourceNames(sourcePageResources.getCOSDictionary())).writeText(pdStream);
+ PDFWriter writer = new PDFWriter(uniqueName, getResourceNames(sourcePageResources.getCOSDictionary()),
+ currentMCID);
+ newStream = writer.writeText(pdStream);
+ currentMCID = writer.getCurrentMCID();
+
}
pdStream = new PDStream(sourceDoc, new ByteArrayInputStream(newStream.getBytes("ISO-8859-1")));
mergeXObj(sourcePageResources.getCOSDictionary(), fontinfo, uniqueName);
Modified: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxImageHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxImageHandler.java?rev=1657884&r1=1657883&r2=1657884&view=diff
==============================================================================
--- xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxImageHandler.java (original)
+++ xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxImageHandler.java Fri Feb 6 16:23:25 2015
@@ -70,7 +70,9 @@ public class PDFBoxImageHandler extends
}
FontInfo fontinfo = (FontInfo)context.getHint("fontinfo");
String stream = createStreamForPDF(pdfImage, pdfContext.getPage(), pdfContext.getUserAgent(),
- pageAdjust, fontinfo, pos, pdfContext.getPageNumbers());
+ pageAdjust, fontinfo, pos, pdfContext.getPageNumbers(),
+ pdfContext.getPdfLogicalStructureHandler(), pdfContext.getCurrentSessionStructElem());
+
if (stream == null) {
return;
}
Modified: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PDFWriter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PDFWriter.java?rev=1657884&r1=1657883&r2=1657884&view=diff
==============================================================================
--- xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PDFWriter.java (original)
+++ xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PDFWriter.java Fri Feb 6 16:23:25 2015
@@ -40,10 +40,12 @@ public class PDFWriter {
protected StringBuilder s = new StringBuilder();
private String key;
private List<COSName> resourceNames;
+ private int currentMCID;
- public PDFWriter(String key, List<COSName> resourceNames) {
+ public PDFWriter(String key, List<COSName> resourceNames, int currentMCID) {
this.key = key;
this.resourceNames = resourceNames;
+ this.currentMCID = currentMCID;
}
public String writeText(PDStream pdStream) throws IOException {
@@ -100,9 +102,20 @@ public class PDFWriter {
s.append("] ");
} else if (c instanceof COSDictionary) {
Collection<COSBase> dictArgs = new ArrayList<COSBase>();
- for (Map.Entry<COSName, COSBase> cn : ((COSDictionary)c).entrySet()) {
- dictArgs.add(cn.getKey());
- dictArgs.add(cn.getValue());
+ if (currentMCID != 0 && op.getOperation().equals("BDC")) {
+ for (Map.Entry<COSName, COSBase> cn : ((COSDictionary)c).entrySet()) {
+ if (cn.getKey().getName().equals("MCID")) {
+ updateMCID(cn, dictArgs);
+ } else {
+ dictArgs.add(cn.getKey());
+ dictArgs.add(cn.getValue());
+ }
+ }
+ } else {
+ for (Map.Entry<COSName, COSBase> cn : ((COSDictionary)c).entrySet()) {
+ dictArgs.add(cn.getKey());
+ dictArgs.add(cn.getValue());
+ }
}
s.append("<<");
readPDFArguments(op, dictArgs);
@@ -114,9 +127,21 @@ public class PDFWriter {
}
}
+ private void updateMCID(Map.Entry<COSName, COSBase> cn, Collection<COSBase> dictArgs) {
+ COSBase cosMCID = cn.getValue();
+ assert cosMCID instanceof COSInteger;
+ COSInteger mcid = (COSInteger) cosMCID;
+ COSInteger updatedID = COSInteger.get(mcid.intValue() + currentMCID);
+ dictArgs.add(cn.getKey());
+ dictArgs.add(updatedID);
+ }
+
protected void addKey(COSName cn) {
if (resourceNames.contains(cn)) {
s.append(key);
}
}
+ protected int getCurrentMCID() {
+ return currentMCID;
+ }
}
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PageParentTreeFinder.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PageParentTreeFinder.java?rev=1657884&view=auto
==============================================================================
--- xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PageParentTreeFinder.java (added)
+++ xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PageParentTreeFinder.java Fri Feb 6 16:23:25 2015
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+package org.apache.fop.render.pdf.pdfbox;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSInteger;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSObject;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.common.PDNumberTreeNode;
+import org.apache.pdfbox.pdmodel.graphics.PDXObject;
+
+public class PageParentTreeFinder {
+
+ PDPage srcPage;
+ public PageParentTreeFinder(PDPage srcPage) {
+ this.srcPage = srcPage;
+ }
+
+ public COSArray getPageParentTreeArray(PDDocument srcDoc) {
+ int position = srcPage.getCOSDictionary().getInt(COSName.STRUCT_PARENTS);
+ if (position == -1) {
+ position = findXObjectStructParent();
+ }
+ if (position != -1) {
+ PDNumberTreeNode srcNumberTreeNode = srcDoc.getDocumentCatalog().getStructureTreeRoot().getParentTree();
+ COSArray parentTreeKids = traverseParentTree(srcNumberTreeNode.getCOSDictionary(), position);
+ return removeNonCOSObjects(parentTreeKids);
+ }
+ return new COSArray();
+ }
+ //TODO handle structural hierarchy in xboject stream
+ private int findXObjectStructParent() {
+ int position = -1;
+ Map<String, PDXObject> mapXObject = srcPage.findResources().getXObjects();
+ for (PDXObject t : mapXObject.values()) {
+ COSDictionary xObjectDict = (COSDictionary)t.getCOSObject();
+ position = xObjectDict.getInt(COSName.STRUCT_PARENTS);
+ if (position != -1) {
+ return position;
+ }
+ }
+ return position;
+ }
+
+ private COSArray traverseParentTree(COSDictionary numberTreeNodeDict, int position) {
+ COSArray numberTree;
+ COSArray parentTree;
+ List<COSArray> nums = new ArrayList<COSArray>();
+ if (numberTreeNodeDict.containsKey(COSName.NUMS)) {
+ numberTree = (COSArray)numberTreeNodeDict.getItem(COSName.NUMS);
+ return extractMarkedContentParents(numberTree, position);
+ } else {
+ parentTree = (COSArray) numberTreeNodeDict.getDictionaryObject(COSName.KIDS);
+ traverseKids(parentTree, position, nums);
+ }
+ return nums.get(0);
+ }
+
+ private void traverseKids(COSBase kids, int position, List<COSArray> numList) {
+ COSArray pageParentTree;
+ if (!numList.isEmpty()) {
+ return;
+ }
+ if (kids instanceof COSArray) {
+ COSArray kidsArray = (COSArray)kids;
+ for (COSBase kid : kidsArray) {
+ COSObject kidCOSObj = (COSObject) kid;
+ traverseKids(kidCOSObj, position, numList);
+ }
+ } else if (kids instanceof COSObject) {
+ COSObject kidCOSObj = (COSObject) kids;
+ if (kidCOSObj.getDictionaryObject(COSName.NUMS) == null) {
+ traverseKids(kidCOSObj.getDictionaryObject(COSName.KIDS), position, numList);
+
+ } else {
+ if (kidCOSObj.getDictionaryObject(COSName.LIMITS) != null) {
+ COSArray kidCOSArray = (COSArray) kidCOSObj.getDictionaryObject(COSName.LIMITS);
+ int lowerLimit = ((COSInteger) kidCOSArray.get(0)).intValue();
+ int upperLimit = ((COSInteger) kidCOSArray.get(1)).intValue();
+ if (lowerLimit <= position && position <= upperLimit) {
+ COSArray nums = (COSArray) kidCOSObj.getDictionaryObject(COSName.NUMS);
+ pageParentTree = (COSArray) nums.getObject(((position - lowerLimit) * 2) + 1);
+ numList.add(pageParentTree);
+ return;
+ }
+ } else {
+ COSArray nums = (COSArray) kidCOSObj.getDictionaryObject(COSName.NUMS);
+ numList.add(extractMarkedContentParents(nums, position));
+ }
+ }
+ }
+ }
+
+ private COSArray extractMarkedContentParents(COSArray numberTree, int position) {
+ COSBase tempObject;
+ boolean keyFlag = false;
+ for (COSBase kid : numberTree) {
+ if (keyFlag) {
+ if (kid instanceof COSObject) {
+ tempObject = ((COSObject)kid).getObject();
+ return (COSArray)tempObject;
+ } else if (kid instanceof COSArray) {
+ return (COSArray)kid;
+ }
+ }
+ if (kid instanceof COSInteger) {
+ int temp = ((COSInteger)kid).intValue();
+ if (temp == position) {
+ keyFlag = true;
+ }
+ }
+ }
+ return new COSArray();
+ }
+ private COSArray removeNonCOSObjects(COSArray pageParentTreeArray) {
+ COSArray objectList = new COSArray();
+ for (COSBase entry : pageParentTreeArray) {
+ if (entry instanceof COSObject) {
+ COSObject entryObj = (COSObject)entry;
+ objectList.add(entryObj);
+ }
+ }
+ return objectList;
+ }
+}
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/PageParentTreeFinder.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/StructureTreeMerger.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/StructureTreeMerger.java?rev=1657884&view=auto
==============================================================================
--- xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/StructureTreeMerger.java (added)
+++ xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/StructureTreeMerger.java Fri Feb 6 16:23:25 2015
@@ -0,0 +1,450 @@
+/*
+ * 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.
+ */
+package org.apache.fop.render.pdf.pdfbox;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSInteger;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSObject;
+
+import org.apache.pdfbox.pdmodel.PDPage;
+
+import org.apache.fop.pdf.PDFDictionary;
+import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.pdf.PDFNumber;
+import org.apache.fop.pdf.PDFObject;
+import org.apache.fop.pdf.PDFPage;
+import org.apache.fop.pdf.PDFReference;
+import org.apache.fop.pdf.PDFStructElem;
+import org.apache.fop.render.pdf.PDFLogicalStructureHandler;
+
+public class StructureTreeMerger {
+
+ PDFBoxAdapter adapter;
+ PDFPage targetPage;
+ PDFDocument pdfDoc;
+ private PDPage srcPage;
+ private COSDictionary roleMap;
+ protected PDFStructElem currentSessionElem;
+ private PDFLogicalStructureHandler logicalStructHandler;
+ private Map<Integer, PDFStructElem> structElemCache = new HashMap<Integer, PDFStructElem>();
+ private Map<Integer, PDFStructElem> markedContentMap = new TreeMap<Integer, PDFStructElem>();
+ private int currentMCID;
+ private List<COSObject> topElems = new ArrayList<COSObject>();
+ private COSArray extra = new COSArray();
+
+ public StructureTreeMerger(PDFStructElem currentSessionElem, PDFLogicalStructureHandler logicalStructHandler,
+ PDFBoxAdapter adapter, PDPage srcPage) {
+ this.adapter = adapter;
+ this.srcPage = srcPage;
+ this.targetPage = adapter.getTargetPage();
+ this.pdfDoc = targetPage.getDocument();
+ this.currentMCID = adapter.getCurrentMCID();
+ this.logicalStructHandler = logicalStructHandler;
+ this.currentSessionElem = currentSessionElem;
+ }
+
+ public void setRoleMap(COSDictionary roleMap) {
+ this.roleMap = roleMap;
+ }
+
+ public void copyStructure(COSArray pageParentTreeArray) throws IOException {
+ for (COSBase entry : pageParentTreeArray) {
+ COSObject entryObj = (COSObject)entry;
+ createPageStructElements(entryObj);
+ }
+ createParents(pageParentTreeArray);
+ for (COSObject top : topElems) {
+ findLeafNodesInPageFromStructElemObjects(top);
+ }
+ createParents(extra);
+ addToPageParentTreeArray();
+ removeNullPlaceholders();
+ }
+
+ public void createDirectDescendants(COSBase base, PDFStructElem parent) throws IOException {
+ if (base instanceof COSDictionary) {
+ COSDictionary baseDict = (COSDictionary)base;
+ if (baseDict.keySet().contains(COSName.K)) {
+ createDirectDescendants(baseDict.getItem(COSName.K), parent);
+ }
+ } else if (base instanceof COSArray) {
+ COSArray array = (COSArray)base;
+ for (int i = 0; i < array.size(); i++) {
+ createDirectDescendants(array.get(i), parent);
+ }
+ } else {
+ assert base instanceof COSObject;
+ COSObject obj = (COSObject)base;
+ createAndRegisterStructElem(obj);
+ PDFStructElem elem = structElemCache.get(obj.getObjectNumber().intValue());
+ copyElemEntries(obj, elem);
+ parent.addKid(elem);
+ elem.setParent(parent);
+ COSBase objKid = obj.getItem(COSName.K);
+ if (objKid != null) {
+ createDirectDescendants(objKid, elem);
+ }
+ }
+ }
+
+ public void setCurrentSessionElem() {
+ if (currentSessionElem == null) {
+ currentSessionElem = pdfDoc.getStructureTreeElements()
+ .get(pdfDoc.getStructureTreeElements().size() - 1);
+ }
+ }
+
+ private void createParents(COSArray markedContentParents) throws IOException {
+ for (COSBase entry : markedContentParents) {
+ COSObject elemCos = (COSObject)entry;
+ COSObject elemParent = (COSObject)elemCos.getItem(COSName.P);
+ PDFStructElem elem = structElemCache.get(elemCos.getObjectNumber().intValue());
+ createParents(elemCos, elemParent, elem);
+ }
+ }
+
+ private PDFStructElem createAndRegisterStructElem(COSObject entry) {
+ PDFStructElem elem = new PDFStructElem();
+ pdfDoc.registerStructureElement(elem);
+ structElemCache.put(entry.getObjectNumber().intValue(), elem);
+ return elem;
+ }
+
+ private void copyElemEntries(COSBase base, PDFStructElem elem) throws IOException {
+ assert base instanceof COSObject;
+ COSObject baseObj = (COSObject) base;
+ COSDictionary baseDic = (COSDictionary) baseObj.getObject();
+ COSName[] names = {COSName.TYPE, COSName.S, COSName.PG, COSName.ALT, COSName.LANG, COSName.A,
+ COSName.ACTUAL_TEXT, COSName.T, COSName.E, COSName.C };
+ for (COSName name : names) {
+ if (baseDic.keySet().contains(name)) {
+ if (name.equals(COSName.PG)) {
+ elem.put("Pg", targetPage.makeReference());
+ } else {
+ elem.put(name.getName(), adapter.cloneForNewDocument(baseDic.getItem(name)));
+ }
+ }
+ }
+ adapter.cacheClonedObject(base, elem);
+ }
+
+ private PDFStructElem createPageStructElements(COSObject entry) throws IOException {
+ int objID = entry.getObjectNumber().intValue();
+ if (structElemCache.containsKey(objID)) {
+ return null;
+ }
+ PDFStructElem elem = createAndRegisterStructElem(entry);
+ copyElemEntries(entry, elem);
+ COSDictionary baseDict = (COSDictionary) entry.getObject();
+ COSBase kid = baseDict.getItem(COSName.K);
+ createKids(kid, baseDict, elem, false);
+ return elem;
+ }
+
+ private void createParents(COSObject cosElem, COSObject cosParentElem, PDFStructElem elem) throws IOException {
+ int elemObjectID = cosParentElem.getObjectNumber().intValue();
+ COSDictionary parentElemDictionary = (COSDictionary)cosParentElem.getObject();
+ PDFStructElem elemParent = structElemCache.get(elemObjectID);
+ if (isStructureTreeRoot(parentElemDictionary)) {
+ elem.setParent(currentSessionElem);
+ currentSessionElem.addKid(elem);
+ topElems.add(cosElem);
+ return;
+ } else if (elemParent != null) {
+ checkIlfStructureTypeIsPresent(parentElemDictionary, "TR");
+ if (!checkIlfStructureTypeIsPresent(parentElemDictionary, "TR")) {
+ elem.setParent(elemParent);
+ int position = StructureTreeMergerUtil.findObjectPositionInKidsArray(cosElem);
+ elemParent.addKidInSpecificOrder(position, elem);
+ }
+ } else if (!checkIlfStructureTypeIsPresent(parentElemDictionary, "Document")) {
+ elemParent = createAndRegisterStructElem(cosParentElem);
+ copyElemEntries(cosParentElem, elemParent);
+ elem.setParent(elemParent);
+ fillKidsWithNull(elemParent, (COSDictionary)cosParentElem.getObject());
+ if (((COSName)parentElemDictionary.getDictionaryObject(COSName.S)).getName().equals("TR")) {
+ COSBase rowKids = parentElemDictionary.getItem(COSName.K);
+ createKids(rowKids, parentElemDictionary, elemParent, true);
+ } else {
+ int position = StructureTreeMergerUtil.findObjectPositionInKidsArray(cosElem);
+ elemParent.addKidInSpecificOrder(position, elem);
+ }
+ COSObject parentObj = (COSObject)parentElemDictionary.getItem(COSName.P);
+ createParents(cosParentElem, parentObj, elemParent);
+ } else {
+ elem.setParent(currentSessionElem);
+ int position = StructureTreeMergerUtil.findObjectPositionInKidsArray(cosElem);
+ currentSessionElem.addKidInSpecificOrder(position, elem);
+ topElems.add(cosElem);
+ }
+ }
+
+ private void createKids(COSBase baseKid, COSDictionary parentDict, PDFStructElem parent,
+ boolean originatedFromTableRow) throws IOException {
+ if (baseKid instanceof COSArray) {
+ COSArray baseArray = (COSArray) baseKid;
+ for (COSBase entry : baseArray) {
+ createKids(entry, parentDict, parent, originatedFromTableRow);
+ }
+ } else if (baseKid instanceof COSObject) {
+ COSObject kid = (COSObject)baseKid;
+ createKidFromCOSObject(kid, parentDict, parent, originatedFromTableRow);
+ } else if (baseKid instanceof COSInteger) {
+ if (checkPageEntryInAncestorsRecursively(parentDict)) {
+ PDFNumber num = (PDFNumber)adapter.cloneForNewDocument(baseKid);
+ createKidEntryFromInt(num, parent);
+ }
+ } else if (baseKid instanceof COSDictionary) {
+ COSDictionary mcrDict = (COSDictionary)baseKid;
+ createKidFromCOSDictionary(mcrDict, parent, parentDict);
+ }
+ }
+
+ private void createKidFromCOSObject(COSObject baseObj, COSDictionary parentDict, PDFStructElem parent,
+ boolean originatedFromTableRow) throws IOException {
+ COSBase baseKid = baseObj.getObject();
+ if (baseKid instanceof COSInteger) {
+ COSInteger number = (COSInteger) baseKid;
+ createKids(number, parentDict, parent, originatedFromTableRow);
+ } else {
+ COSDictionary unwrappedDict = (COSDictionary)baseKid;
+ if (unwrappedDict.getDictionaryObject(COSName.S) == null) {
+ COSDictionary mcrDict = (COSDictionary)baseKid;
+ createKidFromCOSDictionary(mcrDict, parent, parentDict);
+ } else if (originatedFromTableRow) {
+ int objID = baseObj.getObjectNumber().intValue();
+ if (structElemCache.get(objID) != null) {
+ PDFStructElem kidElem = structElemCache.get(objID);
+ parent.addKid(kidElem);
+ kidElem.setParent(parent);
+ } else {
+ createkidEntryFromCosObjectForRow(baseObj, parent);
+ }
+ } else {
+ parent.addKid(null);
+ }
+ }
+ }
+
+ private void createkidEntryFromCosObjectForRow(COSObject entree, PDFStructElem parent) throws IOException {
+ int entreeObjID = entree.getObjectNumber().intValue();
+ PDFStructElem elemRef = structElemCache.get(entreeObjID);
+ if (elemRef == null) {
+ elemRef = createAndRegisterStructElem(entree);
+ copyElemEntries(entree, elemRef);
+ COSDictionary baseDict = (COSDictionary) entree.getObject();
+ COSBase kid = baseDict.getItem(COSName.K);
+ createKids(kid, baseDict, elemRef, true);
+ parent.addKid(elemRef);
+ } else {
+ parent.addKid(elemRef);
+ }
+ elemRef.setParent(parent);
+ }
+
+ private boolean checkPageEntryInAncestorsRecursively(COSDictionary elem) {
+ if (elem.containsKey(COSName.PG)) {
+ COSDictionary pageDict = (COSDictionary)elem.getDictionaryObject(COSName.PG);
+ return srcPage.getCOSObject() == pageDict;
+ } else if (elem.containsKey(COSName.P)) {
+ COSDictionary parent = (COSDictionary)elem.getDictionaryObject(COSName.P);
+ return checkPageEntryInAncestorsRecursively(parent);
+ } else {
+ return true;
+ }
+ }
+
+ private boolean isElementFromSourcePage(COSDictionary mrcDict, COSDictionary parentDict) {
+ if (mrcDict.containsKey(COSName.PG)) {
+ COSDictionary page = (COSDictionary)mrcDict.getDictionaryObject(COSName.PG);
+ return srcPage.getCOSObject() == page;
+ } else {
+ return checkPageEntryInAncestorsRecursively(parentDict);
+ }
+ }
+
+ private void createKidFromCOSDictionary(COSDictionary mcrDict, PDFStructElem parent, COSDictionary baseDict)
+ throws IOException {
+ Collection<COSName> exclude = Arrays.asList(COSName.PG);
+ if (isElementFromSourcePage(mcrDict, baseDict)) {
+ PDFDictionary contentItem = (PDFDictionary)adapter.cloneForNewDocument(mcrDict, mcrDict, exclude);
+ if (mcrDict.keySet().contains(COSName.TYPE)) {
+ String type = ((COSName) mcrDict.getDictionaryObject(COSName.TYPE)).getName();
+ if (type.equals("OBJR")) {
+ COSObject obj = (COSObject) mcrDict.getItem(COSName.OBJ);
+ PDFReference referenceObj = ((PDFObject) adapter.getCachedClone(obj)).makeReference();
+ contentItem.put("Obj", referenceObj);
+ updateStructParentAndAddToPageParentTree(referenceObj, parent);
+ } else if (type.equals("MCR")) {
+ updateMCIDEntry(contentItem);
+ markedContentMap.put((((PDFNumber)contentItem.get(COSName.MCID.getName())).getNumber())
+ .intValue(), parent);
+ }
+ }
+ if (mcrDict.keySet().contains(COSName.PG)) {
+ contentItem.put("Pg", targetPage.makeReference());
+ } else {
+ parent.put("Pg", targetPage.makeReference());
+ }
+ parent.addKid(contentItem);
+ } else {
+ parent.addKid(null);
+ }
+ }
+
+ private void createKidEntryFromInt(PDFNumber num, PDFStructElem parent) {
+ num.setNumber(num.getNumber().intValue() + currentMCID);
+ parent.addKid(num);
+ markedContentMap.put(num.getNumber().intValue(), parent);
+ }
+
+ private void updateMCIDEntry(PDFDictionary mcrDictionary) {
+ if (currentMCID > 0) {
+ int oldMCID = (((PDFNumber)mcrDictionary.get("MCID")).getNumber()).intValue();
+ PDFNumber number = new PDFNumber();
+ number.setNumber(oldMCID + currentMCID);
+ mcrDictionary.put("MCID", number);
+ }
+ }
+
+ private void removeNullPlaceholders() {
+ List<PDFStructElem> list = new ArrayList<PDFStructElem>(structElemCache.values());
+ for (PDFStructElem elem : list) {
+ List<PDFObject> kids = elem.getKids();
+ if (kids != null) {
+ kids.removeAll(Collections.singleton(null));
+ }
+ }
+ }
+
+ private boolean isStructureTreeRoot(COSDictionary elem) {
+ if (elem.keySet().contains(COSName.TYPE)) {
+ COSName type = (COSName)elem.getDictionaryObject(COSName.TYPE);
+ return type.equals(COSName.STRUCT_TREE_ROOT);
+ }
+ return false;
+ }
+
+ public void addToPageParentTreeArray() {
+ for (PDFStructElem entry : markedContentMap.values()) {
+ logicalStructHandler.getPageParentTree().add(entry);
+ }
+ }
+
+ private void updateStructParentAndAddToPageParentTree(PDFReference obj, PDFStructElem elem) {
+ PDFObject referenceObj = obj.getObject();
+ assert referenceObj instanceof PDFDictionary;
+ int nextParentTreeKey;
+ PDFDictionary objDict = (PDFDictionary)referenceObj;
+ nextParentTreeKey = logicalStructHandler.getNextParentTreeKey();
+ objDict.put("StructParent", nextParentTreeKey);
+ logicalStructHandler.getParentTree().addToNums(nextParentTreeKey, elem);
+ }
+
+ public void setCurrentSessionElemKid() {
+ PDFNumber num = new PDFNumber();
+ createKidEntryFromInt(num, currentSessionElem);
+ addToPageParentTreeArray();
+ }
+
+ private void findLeafNodesInPageFromStructElemObjects(COSBase entry) throws IOException {
+ if (entry instanceof COSObject) {
+ COSObject entryObj = (COSObject) entry;
+ COSDictionary structElemDictionary = (COSDictionary) entryObj.getObject();
+ COSBase kid = structElemDictionary.getItem(COSName.K);
+ findLeafKids(kid, entryObj);
+ }
+ }
+
+ private void findLeafKids(COSBase kid, COSObject parent) throws IOException {
+ if (kid instanceof COSArray) {
+ COSArray arrayKid = (COSArray)kid;
+ for (COSBase arrayEntry : arrayKid) {
+ findLeafKids(arrayEntry, parent);
+ }
+ } else if (kid instanceof COSObject) {
+ COSObject kidObject = (COSObject)kid;
+ COSBase base = kidObject.getObject();
+ COSDictionary temp = (COSDictionary)base;
+ if (temp.getDictionaryObject(COSName.S) != null && temp.getItem(COSName.K) != null) {
+
+ COSBase tempKids = temp.getItem(COSName.K);
+ findLeafKids(tempKids, kidObject);
+ } else {
+ findLeafKids(temp, parent);
+ }
+ } else if (kid instanceof COSDictionary) {
+ COSDictionary kidDictionary = (COSDictionary)kid;
+ COSDictionary parentDict = (COSDictionary)parent.getObject();
+ if (isElementFromSourcePage(kidDictionary, parentDict)) {
+ PDFStructElem elem = structElemCache.get(parent.getObjectNumber().intValue());
+ if (elem == null) {
+ elem = createAndRegisterStructElem(parent);
+ copyElemEntries(parent, elem);
+ extra.add(parent);
+ createKids(kid, parentDict, elem, false);
+ }
+ }
+ } else {
+ assert kid instanceof COSInteger;
+ COSDictionary parentDict = (COSDictionary)parent.getObject();
+ if (checkPageEntryInAncestorsRecursively(parentDict)) {
+ PDFStructElem elem = structElemCache.get(parent.getObjectNumber().intValue());
+ if (elem == null) {
+ elem = createAndRegisterStructElem(parent);
+ copyElemEntries(parent, elem);
+ createKids(kid, parentDict, elem, false);
+ }
+ }
+ }
+ }
+
+ private void fillKidsWithNull(PDFStructElem elem, COSDictionary baseElem) {
+ COSBase baseArray = baseElem.getItem(COSName.K);
+ if (baseArray instanceof COSArray) {
+ COSArray array = (COSArray)baseArray;
+ int size = array.size();
+ for (int i = 0; i < size; i++) {
+ elem.addKid(null);
+ }
+ }
+ }
+
+ private boolean checkIlfStructureTypeIsPresent(COSDictionary elemDictionary, String type) {
+ String potentialCustomElemType = ((COSName)elemDictionary.getDictionaryObject(COSName.S)).getName();
+ if (type.equals(potentialCustomElemType)) {
+ return true;
+ } else {
+ List<String> rolemapValues = StructureTreeMergerUtil.findRoleMapKeyByValue(type, roleMap);
+ return rolemapValues.contains(potentialCustomElemType);
+ }
+ }
+
+}
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/StructureTreeMerger.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/StructureTreeMergerUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/StructureTreeMergerUtil.java?rev=1657884&view=auto
==============================================================================
--- xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/StructureTreeMergerUtil.java (added)
+++ xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/StructureTreeMergerUtil.java Fri Feb 6 16:23:25 2015
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+package org.apache.fop.render.pdf.pdfbox;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSObject;
+
+public final class StructureTreeMergerUtil {
+
+ private StructureTreeMergerUtil() { }
+
+ public static int findObjectPositionInKidsArray(COSObject kid) {
+ COSObject parent = (COSObject) kid.getItem(COSName.P);
+ COSBase kids = parent.getItem(COSName.K);
+ if (kids instanceof COSArray) {
+ COSArray kidsArray = (COSArray)kids;
+ return kidsArray.indexOfObject(kid);
+ } else {
+ return 0;
+ }
+ }
+
+ public static List<String> findRoleMapKeyByValue(String type, COSDictionary roleMap) {
+ List<String> keys = new ArrayList<String>();
+ if (roleMap != null) {
+ for (Entry<COSName, COSBase> entry : roleMap.entrySet()) {
+ String value = ((COSName)entry.getValue()).getName();
+ String key = entry.getKey().getName();
+ if (type.equals(value)) {
+ keys.add(key);
+ }
+ }
+ }
+ return keys;
+ }
+}
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/StructureTreeMergerUtil.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/TaggedPDFConductor.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/TaggedPDFConductor.java?rev=1657884&view=auto
==============================================================================
--- xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/TaggedPDFConductor.java (added)
+++ xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/TaggedPDFConductor.java Fri Feb 6 16:23:25 2015
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+package org.apache.fop.render.pdf.pdfbox;
+
+import java.io.IOException;
+
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSName;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDMarkInfo;
+
+import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.pdf.PDFName;
+import org.apache.fop.pdf.PDFPage;
+import org.apache.fop.pdf.PDFStructElem;
+import org.apache.fop.render.pdf.PDFLogicalStructureHandler;
+
+public class TaggedPDFConductor {
+
+ private PDPage srcPage;
+ private PDFDocument pdfDoc;
+ private PDFPage targetPage;
+ private DocumentRootModifier rootMod;
+ private StructureTreeMerger merger;
+
+ public TaggedPDFConductor(PDFStructElem currentSessionElem,
+ PDFLogicalStructureHandler logicalStructHandler, PDPage srcPage,
+ PDFBoxAdapter adapter) {
+ this.srcPage = srcPage;
+ this.targetPage = adapter.getTargetPage();
+ this.pdfDoc = targetPage.getDocument();
+ this.rootMod = new DocumentRootModifier(adapter, pdfDoc);
+ merger = new StructureTreeMerger(currentSessionElem, logicalStructHandler, adapter, srcPage);
+ }
+
+ public void handleLogicalStructure(PDDocument srcDoc) throws IOException {
+ if (isInputPDFTagged(srcDoc) && isStructureTreeRootNull(srcDoc)) {
+ merger.setCurrentSessionElem();
+ COSDictionary strucRootDict = (COSDictionary)srcDoc.getDocumentCatalog().getStructureTreeRoot()
+ .getCOSObject();
+ rootMod.structTreeRootEntriesToCopy(strucRootDict);
+ if (!isParentTreeIsPresent(strucRootDict)) {
+ merger.createDirectDescendants(strucRootDict, merger.currentSessionElem);
+ } else {
+ PageParentTreeFinder markedContentsParentFinder = new PageParentTreeFinder(srcPage);
+ COSArray markedContentsParents = markedContentsParentFinder.getPageParentTreeArray(srcDoc);
+ COSDictionary roleMap = (COSDictionary)strucRootDict.getDictionaryObject(COSName.ROLE_MAP);
+ if (roleMap != null) {
+ merger.setRoleMap(roleMap);
+ }
+ merger.copyStructure(markedContentsParents);
+ }
+ }
+ configureCurrentSessionElem(srcDoc);
+ }
+
+ private void configureCurrentSessionElem(PDDocument srcDoc) {
+ if (!(isInputPDFTagged(srcDoc) && isStructureTreeRootNull(srcDoc))) {
+ merger.setCurrentSessionElemKid();
+ merger.currentSessionElem.put(COSName.PG.getName(), targetPage.makeReference());
+ } else {
+ merger.currentSessionElem.put("S", new PDFName("Div"));
+ }
+ }
+ private boolean isInputPDFTagged(PDDocument srcDoc) {
+ PDMarkInfo mark = srcDoc.getDocumentCatalog().getMarkInfo();
+ return mark != null && mark.isMarked();
+ }
+
+ private boolean isStructureTreeRootNull(PDDocument srcDoc) {
+ return srcDoc.getDocumentCatalog().getStructureTreeRoot() != null;
+ }
+
+ private boolean isParentTreeIsPresent(COSDictionary strucRootDict) {
+ return strucRootDict.keySet().contains(COSName.PARENT_TREE);
+ }
+}
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/src/java/org/apache/fop/render/pdf/pdfbox/TaggedPDFConductor.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/DocumentRootModifierTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/DocumentRootModifierTestCase.java?rev=1657884&view=auto
==============================================================================
--- xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/DocumentRootModifierTestCase.java (added)
+++ xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/DocumentRootModifierTestCase.java Fri Feb 6 16:23:25 2015
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+package org.apache.fop.render.pdf;
+
+import java.awt.geom.Rectangle2D;
+import java.io.IOException;
+import java.util.HashMap;
+
+import org.junit.Test;
+
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSName;
+
+import org.apache.fop.pdf.PDFArray;
+import org.apache.fop.pdf.PDFDictionary;
+import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.pdf.PDFName;
+import org.apache.fop.pdf.PDFPage;
+import org.apache.fop.pdf.PDFResources;
+import org.apache.fop.pdf.PDFStructTreeRoot;
+import org.apache.fop.render.pdf.pdfbox.DocumentRootModifier;
+import org.apache.fop.render.pdf.pdfbox.PDFBoxAdapter;
+
+import junit.framework.Assert;
+
+public class DocumentRootModifierTestCase {
+
+ @Test
+ public void testStructTreeRootEntriesToCopy() throws IOException {
+ Rectangle2D r = new Rectangle2D.Double();
+ PDFPage page = new PDFPage(new PDFResources(0), 0, r, r, r, r);
+ page.setObjectNumber(1);
+ PDFDocument pdfDoc = new PDFDocument("");
+ page.setDocument(pdfDoc);
+ pdfDoc.makeStructTreeRoot(null);
+ PDFStructTreeRoot structTreeRoot = pdfDoc.getRoot().getStructTreeRoot();
+ PDFDictionary rootBaseRoleMap = new PDFDictionary();
+ PDFName para = new PDFName("P");
+ rootBaseRoleMap.put("MyPara", para);
+ structTreeRoot.put("RoleMap", rootBaseRoleMap);
+ PDFBoxAdapter adapter = new PDFBoxAdapter(page, new HashMap(), new HashMap<Integer, PDFArray>());
+ COSDictionary root = new COSDictionary();
+ COSDictionary mapRole = new COSDictionary();
+ mapRole.setName("Icon", "Figure");
+ root.setItem(COSName.ROLE_MAP, mapRole);
+ DocumentRootModifier modifier = new DocumentRootModifier(adapter, pdfDoc);
+ modifier.structTreeRootEntriesToCopy(root);
+ structTreeRoot = pdfDoc.getRoot().getStructTreeRoot();
+ PDFDictionary baseRoot = (PDFDictionary) structTreeRoot.get("RoleMap");
+ PDFName nameIcon = (PDFName) baseRoot.get("Icon");
+ PDFName myPara = (PDFName)baseRoot.get("MyPara");
+ String test = nameIcon.getName();
+ String expected = "Figure";
+ Assert.assertEquals(test, expected);
+ test = myPara.getName();
+ expected = "P";
+ Assert.assertEquals(test, expected);
+ }
+}
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/DocumentRootModifierTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java?rev=1657884&r1=1657883&r2=1657884&view=diff
==============================================================================
--- xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java (original)
+++ xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java Fri Feb 6 16:23:25 2015
@@ -42,6 +42,9 @@ import org.apache.fop.render.pdf.pdfbox.
import org.apache.fop.render.pdf.pdfbox.PDFBoxImageHandler;
import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import org.apache.commons.io.IOUtils;
import org.apache.fontbox.cff.CFFFont;
import org.apache.fontbox.cff.CFFParser;
@@ -57,6 +60,7 @@ import org.apache.xmlgraphics.image.load
import org.apache.xmlgraphics.image.loader.ImageSource;
import org.apache.xmlgraphics.image.loader.impl.DefaultImageContext;
+import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fonts.CustomFont;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontType;
@@ -312,7 +316,6 @@ public class PDFBoxAdapterTestCase {
Assert.assertTrue(pageNumbers.size() == 4);
PDFAnnotList annots = (PDFAnnotList) pdfpage.get("Annots");
Assert.assertEquals(annots.toPDFString(), "[\n9 0 R\n12 0 R\n]");
-// pdfdoc.output(System.out);
doc.close();
}
@@ -335,7 +338,9 @@ public class PDFBoxAdapterTestCase {
pdfdoc.assignObjectNumber(g);
pdfpage.addGState(g);
PDFContentGenerator con = new PDFContentGenerator(pdfdoc, null, null);
- PDFRenderingContext c = new PDFRenderingContext(null, con, pdfpage, null);
+ FOUserAgent mockedAgent = mock(FOUserAgent.class);
+ when(mockedAgent.isAccessibilityEnabled()).thenReturn(false);
+ PDFRenderingContext c = new PDFRenderingContext(mockedAgent, con, pdfpage, null);
c.setPageNumbers(new HashMap<Integer, PDFArray>());
new PDFBoxImageHandler().handleImage(c, img, new Rectangle());
PDFResources res = c.getPage().getPDFResources();
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/PageParentTreeFinderTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/PageParentTreeFinderTestCase.java?rev=1657884&view=auto
==============================================================================
--- xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/PageParentTreeFinderTestCase.java (added)
+++ xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/PageParentTreeFinderTestCase.java Fri Feb 6 16:23:25 2015
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+package org.apache.fop.render.pdf;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSObject;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+
+import org.apache.fop.render.pdf.pdfbox.PageParentTreeFinder;
+
+import junit.framework.Assert;
+
+public class PageParentTreeFinderTestCase {
+ private static final String LINK = "test/resources/linkTagged.pdf";
+
+ @Test
+ public void testGetPageParentTreeArray() throws IOException {
+ PDDocument doc = PDDocument.load(LINK);
+ PDPage srcPage = doc.getPage(0);
+ PageParentTreeFinder finder = new PageParentTreeFinder(srcPage);
+ COSArray markedContentParents = finder.getPageParentTreeArray(doc);
+ Assert.assertEquals(markedContentParents.size(), 3);
+ COSObject firstObj = (COSObject)markedContentParents.get(0);
+ COSObject secObj = (COSObject)markedContentParents.get(1);
+ COSArray firstKids = (COSArray)firstObj.getDictionaryObject(COSName.K);
+ COSDictionary firstKid = (COSDictionary) firstKids.get(0);
+ int test = firstKid.getInt("MCID");
+ int expected = 0;
+ Assert.assertEquals(test, expected);
+ COSDictionary firstKidBrother = (COSDictionary)firstKids.get(2);
+ test = firstKidBrother.getInt("MCID");
+ expected = 2;
+ Assert.assertEquals(test, expected);
+ COSArray secKidsArray = (COSArray)secObj.getDictionaryObject(COSName.K);
+ COSDictionary secondKid = (COSDictionary)secKidsArray.get(0);
+ test = secondKid.getInt("MCID");
+ expected = 1;
+ Assert.assertEquals(test, expected);
+ }
+}
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/PageParentTreeFinderTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/StructureTreeMergerTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/StructureTreeMergerTestCase.java?rev=1657884&view=auto
==============================================================================
--- xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/StructureTreeMergerTestCase.java (added)
+++ xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/StructureTreeMergerTestCase.java Fri Feb 6 16:23:25 2015
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+package org.apache.fop.render.pdf;
+
+import java.awt.geom.Rectangle2D;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+
+import org.junit.Test;
+
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSDictionary;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+
+import org.apache.fop.pdf.PDFArray;
+import org.apache.fop.pdf.PDFDictionary;
+import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.pdf.PDFName;
+import org.apache.fop.pdf.PDFNumber;
+import org.apache.fop.pdf.PDFPage;
+import org.apache.fop.pdf.PDFReference;
+import org.apache.fop.pdf.PDFResources;
+import org.apache.fop.pdf.PDFStructElem;
+
+import org.apache.fop.render.pdf.pdfbox.PDFBoxAdapter;
+import org.apache.fop.render.pdf.pdfbox.PageParentTreeFinder;
+import org.apache.fop.render.pdf.pdfbox.StructureTreeMerger;
+
+import junit.framework.Assert;
+
+public class StructureTreeMergerTestCase {
+ private static final String LINK = "test/resources/linkTagged.pdf";
+ private static final String NoParentTree = "test/resources/NoParentTree.pdf";
+ private PDFPage pdfPage;
+ private PDFDocument pdfDoc;
+ private PDFBoxAdapter adapter;
+
+ @Test
+ public void testCopyStructure() throws IOException {
+ setUp();
+ PDDocument doc = PDDocument.load(LINK);
+ PDPage srcPage = doc.getPage(0);
+ PageParentTreeFinder finder = new PageParentTreeFinder(srcPage);
+ COSArray markedContentParents = finder.getPageParentTreeArray(doc);
+ PDFStructElem elem = new PDFStructElem();
+ elem.setObjectNumber(2);
+ adapter = new PDFBoxAdapter(pdfPage, new HashMap(), new HashMap<Integer, PDFArray>());
+ PDFLogicalStructureHandler handler = setUpPDFLogicalStructureHandler();
+ StructureTreeMerger merger = new StructureTreeMerger(elem, handler, adapter, srcPage);
+ merger.copyStructure(markedContentParents);
+ PDFArray array = handler.getPageParentTree();
+ checkMarkedContentsParentsForLinkTest(array);
+ PDFStructElem first = (PDFStructElem)array.get(0);
+ checkParentForLinkTest(first, 0);
+ }
+
+ @Test
+ public void testCreateDirectDescendants() throws IOException {
+ setUp();
+ PDDocument doc = PDDocument.load(NoParentTree);
+ PDPage srcPage = doc.getPage(0);
+ PDFStructElem elem = new PDFStructElem();
+ elem.setObjectNumber(2);
+ adapter = new PDFBoxAdapter(pdfPage, new HashMap(), new HashMap<Integer, PDFArray>());
+ PDFLogicalStructureHandler handler = setUpPDFLogicalStructureHandler();
+ StructureTreeMerger merger = new StructureTreeMerger(elem, handler, adapter, srcPage);
+ COSDictionary strucRootDict = (COSDictionary)doc.getDocumentCatalog().getStructureTreeRoot()
+ .getCOSObject();
+ merger.createDirectDescendants(strucRootDict, elem);
+ checkNoParentTree(elem, 0);
+ }
+
+ private void checkMarkedContentsParentsForLinkTest(PDFArray array) {
+ PDFStructElem first = (PDFStructElem)array.get(0);
+ List firstKids = first.getKids();
+ PDFDictionary firstKid = (PDFDictionary) firstKids.get(0);
+ int test = ((PDFNumber)firstKid.get("MCID")).getNumber().intValue();
+ int expected = 0;
+ Assert.assertEquals(test, expected);
+ PDFDictionary firstKidSibling = (PDFDictionary) firstKids.get(2);
+ test = ((PDFNumber)firstKidSibling.get("MCID")).getNumber().intValue();
+ expected = 2;
+ Assert.assertEquals(test, expected);
+ PDFStructElem second = (PDFStructElem)array.get(1);
+ List secondKids = second.getKids();
+ PDFDictionary secKid = (PDFDictionary) secondKids.get(0);
+ test = ((PDFNumber)secKid.get("MCID")).getNumber().intValue();
+ expected = 1;
+ Assert.assertEquals(test, expected);
+ }
+
+ private void checkParentForLinkTest(PDFStructElem elem, int index) {
+ String [] types = {"Sect", "Part"};
+ PDFStructElem parent = (PDFStructElem)((PDFReference)elem.get("P")).getObject();
+ if (index != 2) {
+ String test = ((PDFName)parent.get("S")).getName();
+ String expected = types[index];
+ Assert.assertEquals(test, expected);
+ index++;
+ checkParentForLinkTest(parent, index);
+ }
+ }
+
+ private void setUp() {
+ Rectangle2D r = new Rectangle2D.Double();
+ pdfPage = new PDFPage(new PDFResources(0), 0, r, r, r, r);
+ pdfDoc = new PDFDocument(" ");
+ pdfDoc.makeStructTreeRoot(null);
+ pdfPage.setObjectNumber(1);
+ pdfPage.setDocument(pdfDoc);
+ }
+
+ private PDFLogicalStructureHandler setUpPDFLogicalStructureHandler() {
+ PDFLogicalStructureHandler handler = new PDFLogicalStructureHandler(pdfDoc);
+ handler.getParentTree().setDocument(pdfDoc);
+ handler.startPage(pdfPage);
+ return handler;
+ }
+
+ private void checkNoParentTree(PDFStructElem elem, int index) {
+ String [] types = {"Document", "Part"};
+ if (index != 2) {
+ PDFStructElem kid = (PDFStructElem)elem.getKids().get(0);
+ String test = ((PDFName)kid.get("S")).getName();
+ String expected = types[index];
+ Assert.assertEquals(test, expected);
+ index++;
+ checkNoParentTree(kid, index);
+ }
+ }
+}
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/StructureTreeMergerTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/TaggedPDFConductorTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/TaggedPDFConductorTestCase.java?rev=1657884&view=auto
==============================================================================
--- xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/TaggedPDFConductorTestCase.java (added)
+++ xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/TaggedPDFConductorTestCase.java Fri Feb 6 16:23:25 2015
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+package org.apache.fop.render.pdf;
+
+import java.awt.geom.Rectangle2D;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+
+import org.junit.Test;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+
+import org.apache.fop.pdf.PDFArray;
+import org.apache.fop.pdf.PDFDictionary;
+import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.pdf.PDFName;
+import org.apache.fop.pdf.PDFNumber;
+import org.apache.fop.pdf.PDFObject;
+import org.apache.fop.pdf.PDFPage;
+import org.apache.fop.pdf.PDFResources;
+import org.apache.fop.pdf.PDFStructElem;
+import org.apache.fop.render.pdf.pdfbox.PDFBoxAdapter;
+import org.apache.fop.render.pdf.pdfbox.TaggedPDFConductor;
+
+import junit.framework.Assert;
+
+public class TaggedPDFConductorTestCase {
+ private static final String LINK = "test/resources/linkTagged.pdf";
+ private static final String HELLO = "test/resources/helloWorld.pdf";
+ private static final String TABLE = "test/resources/emptyRowTable.pdf";
+ private static final String OTF = "test/resources/otf.pdf";
+ private PDFPage pdfPage;
+ private PDFDocument pdfDoc;
+
+ @Test
+ public void testHandleLogicalStructure() throws IOException {
+ PDFStructElem elem = new PDFStructElem();
+ runConductor(LINK, elem);
+ checkStructure(elem, 0);
+
+ elem = new PDFStructElem();
+ runConductor(HELLO, elem);
+ PDFNumber mcid = (PDFNumber)elem.getKids().get(0);
+ int test = mcid.getNumber().intValue();
+ Assert.assertEquals(test, 0);
+
+ elem = new PDFStructElem();
+ runConductor(TABLE, elem);
+ Assert.assertEquals(print(elem), "/Div/Part/Sect/Table/TBody/TR/TD/P/TD/P/TR/TD/TD");
+
+ elem = new PDFStructElem();
+ runConductor(OTF, elem);
+ Assert.assertEquals(print(elem), "/Div/Part/Art/P/Span");
+ }
+
+ private String print(PDFStructElem x) throws IOException {
+ StringBuilder sb = new StringBuilder(x.get("S").toString());
+ for (PDFObject k : x.getKids()) {
+ if (k instanceof PDFStructElem) {
+ sb.append(print((PDFStructElem) k));
+ }
+ }
+ return sb.toString();
+ }
+
+ private void runConductor(String pdf, PDFStructElem elem) throws IOException {
+ setUp();
+ PDDocument doc = PDDocument.load(pdf);
+ PDPage srcPage = doc.getPage(0);
+ elem.setObjectNumber(2);
+ PDFBoxAdapter adapter = new PDFBoxAdapter(
+ pdfPage, new HashMap(), new HashMap<Integer, PDFArray>());
+ PDFLogicalStructureHandler handler = setUpPDFLogicalStructureHandler();
+ new TaggedPDFConductor(elem, handler, srcPage, adapter).handleLogicalStructure(doc);
+ }
+
+ private void setUp() {
+ Rectangle2D r = new Rectangle2D.Double();
+ pdfPage = new PDFPage(new PDFResources(0), 0, r, r, r, r);
+ pdfDoc = new PDFDocument(" ");
+ pdfDoc.makeStructTreeRoot(null);
+ pdfPage.setObjectNumber(1);
+ pdfPage.setDocument(pdfDoc);
+ }
+
+ private PDFLogicalStructureHandler setUpPDFLogicalStructureHandler() {
+ PDFLogicalStructureHandler handler = new PDFLogicalStructureHandler(pdfDoc);
+ handler.getParentTree().setDocument(pdfDoc);
+ handler.startPage(pdfPage);
+ return handler;
+ }
+
+ private void checkStructure(PDFStructElem elem, int index) {
+ String [] types = {"Part", "Sect", "P"};
+ List<PDFObject> list = elem.getKids();
+ if (index != 3) {
+ PDFStructElem kid = (PDFStructElem)list.get(0);
+ String test = ((PDFName)kid.get("S")).getName();
+ String expected = types[index];
+ Assert.assertEquals(test, expected);
+ index++;
+ checkStructure(kid, index);
+ } else {
+ PDFDictionary firstKid = (PDFDictionary) list.get(0);
+ int test = ((PDFNumber)firstKid.get("MCID")).getNumber().intValue();
+ int expected = 0;
+ Assert.assertEquals(test, expected);
+ PDFDictionary firstKidSibling = (PDFDictionary) list.get(2);
+ test = ((PDFNumber)firstKidSibling.get("MCID")).getNumber().intValue();
+ expected = 2;
+ Assert.assertEquals(test, expected);
+ PDFStructElem second = (PDFStructElem)list.get(1);
+ List secondKids = second.getKids();
+ PDFStructElem secKid = (PDFStructElem) secondKids.get(0);
+ List secondKidKids = secKid.getKids();
+ PDFDictionary leafElem = (PDFDictionary)secondKidKids.get(0);
+ test = ((PDFNumber)leafElem.get("MCID")).getNumber().intValue();
+ expected = 1;
+ Assert.assertEquals(test, expected);
+ }
+ }
+}
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/java/org/apache/fop/render/pdf/TaggedPDFConductorTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/NoParentTree.pdf
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/NoParentTree.pdf?rev=1657884&view=auto
==============================================================================
Binary file - no diff available.
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/NoParentTree.pdf
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/emptyRowTable.pdf
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/emptyRowTable.pdf?rev=1657884&view=auto
==============================================================================
Binary file - no diff available.
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/emptyRowTable.pdf
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/helloWorld.pdf
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/helloWorld.pdf?rev=1657884&view=auto
==============================================================================
Binary file - no diff available.
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/helloWorld.pdf
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/linkTagged.pdf
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/linkTagged.pdf?rev=1657884&view=auto
==============================================================================
Binary file - no diff available.
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/linkTagged.pdf
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/otf.pdf
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/otf.pdf?rev=1657884&view=auto
==============================================================================
Binary file - no diff available.
Propchange: xmlgraphics/fop-pdf-images/branches/Temp_MergeTaggedPDF/test/resources/otf.pdf
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org