diff --git a/fop-core/src/main/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java b/fop-core/src/main/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java
index 3ba4babb75c..c7a8eb16465 100644
--- a/fop-core/src/main/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java
+++ b/fop-core/src/main/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java
@@ -29,6 +29,7 @@
import org.apache.fop.accessibility.StructureTreeEventHandler;
import org.apache.fop.fo.DelegatingFOEventHandler;
import org.apache.fop.fo.FOEventHandler;
+import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FOText;
import org.apache.fop.fo.extensions.ExternalDocument;
import org.apache.fop.fo.flow.AbstractRetrieveMarker;
@@ -786,6 +787,22 @@ public void run() {
super.restoreState(retrieveMarker);
}
+ @Override
+ public void endRestoreState(RetrieveMarker retrieveMarker) {
+ boolean isInsideArtifact = false;
+ FONode obj = retrieveMarker.getParent();
+ while (obj != null && !isInsideArtifact) {
+ if (obj instanceof CommonAccessibilityHolder && isArtifact((CommonAccessibilityHolder)obj)) {
+ isInsideArtifact = true;
+ } else {
+ obj = obj.getParent();
+ }
+ }
+ if (isInsideArtifact && !converters.isEmpty()) {
+ converter = converters.pop();
+ }
+ }
+
@SuppressWarnings("unchecked")
private void restoreRetrieveMarkerState(AbstractRetrieveMarker retrieveMarker) {
State state = states.get(retrieveMarker);
diff --git a/fop-core/src/main/java/org/apache/fop/fo/FOEventHandler.java b/fop-core/src/main/java/org/apache/fop/fo/FOEventHandler.java
index 1f1611fb4e2..f71509cd716 100644
--- a/fop-core/src/main/java/org/apache/fop/fo/FOEventHandler.java
+++ b/fop-core/src/main/java/org/apache/fop/fo/FOEventHandler.java
@@ -571,6 +571,9 @@ public void endRetrieveMarker(RetrieveMarker retrieveMarker) {
public void restoreState(RetrieveMarker retrieveMarker) {
}
+ public void endRestoreState(RetrieveMarker retrieveMarker) {
+ }
+
/**
* Process the start of a retrieve-table-marker.
*
diff --git a/fop-core/src/main/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java b/fop-core/src/main/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java
index f6964911099..e5839fafe40 100644
--- a/fop-core/src/main/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java
+++ b/fop-core/src/main/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java
@@ -212,6 +212,7 @@ public void bindMarker(Marker marker) {
try {
restoreFOEventHandlerState();
cloneFromMarker(marker);
+ endRestoreFOEventHandlerState();
} catch (FOPException exc) {
getFOValidationEventProducer().markerCloningFailed(this,
marker.getMarkerClassName(), exc, getLocator());
@@ -223,6 +224,8 @@ public void bindMarker(Marker marker) {
protected abstract void restoreFOEventHandlerState();
+ protected abstract void endRestoreFOEventHandlerState();
+
/**
* Return the value for the retrieve-class-name
* property
diff --git a/fop-core/src/main/java/org/apache/fop/fo/flow/RetrieveMarker.java b/fop-core/src/main/java/org/apache/fop/fo/flow/RetrieveMarker.java
index 2f2b7e5a404..3c6a7e98a15 100644
--- a/fop-core/src/main/java/org/apache/fop/fo/flow/RetrieveMarker.java
+++ b/fop-core/src/main/java/org/apache/fop/fo/flow/RetrieveMarker.java
@@ -126,4 +126,8 @@ protected void restoreFOEventHandlerState() {
getFOEventHandler().restoreState(this);
}
+ @Override
+ protected void endRestoreFOEventHandlerState() {
+ getFOEventHandler().endRestoreState(this);
+ }
}
diff --git a/fop-core/src/main/java/org/apache/fop/fo/flow/RetrieveTableMarker.java b/fop-core/src/main/java/org/apache/fop/fo/flow/RetrieveTableMarker.java
index 8340736c7c7..ef0e027cdec 100644
--- a/fop-core/src/main/java/org/apache/fop/fo/flow/RetrieveTableMarker.java
+++ b/fop-core/src/main/java/org/apache/fop/fo/flow/RetrieveTableMarker.java
@@ -158,4 +158,8 @@ protected void restoreFOEventHandlerState() {
getFOEventHandler().restoreState(this);
}
+ @Override
+ protected void endRestoreFOEventHandlerState() {
+
+ }
}
diff --git a/fop-core/src/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java b/fop-core/src/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java
index cf8aaee98c7..5350fb560c7 100644
--- a/fop-core/src/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java
+++ b/fop-core/src/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java
@@ -20,10 +20,13 @@
package org.apache.fop.accessibility.fo;
import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
+import java.util.List;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
@@ -34,6 +37,7 @@
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
@@ -46,15 +50,22 @@
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
-
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.apache.commons.io.IOUtils;
+import org.apache.pdfbox.Loader;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.documentinterchange.markedcontent.PDMarkedContent;
+import org.apache.pdfbox.text.PDFMarkedContentExtractor;
import org.apache.fop.accessibility.StructureTree2SAXEventAdapter;
import org.apache.fop.accessibility.StructureTreeEventHandler;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.Fop;
+import org.apache.fop.apps.FopFactory;
+import org.apache.fop.apps.MimeConstants;
import org.apache.fop.fo.FODocumentParser;
import org.apache.fop.fo.FODocumentParser.FOEventHandlerFactory;
import org.apache.fop.fo.FOEventHandler;
@@ -242,6 +253,83 @@ public void testSVGArtifact() throws Exception {
+ "");
}
+ @Test
+ public void testMultipleStaticContentArtifact() throws FOPException,
+ TransformerException, IOException {
+ FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
+ FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
+ foUserAgent.setAccessibility(true);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);
+ TransformerFactory factory = TransformerFactory.newInstance();
+ Transformer transformer = factory.newTransformer();
+
+ String fo = ""
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " 1\n"
+ + " A\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " 2\n"
+ + " B\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + "";
+ Source src = new StreamSource(new ByteArrayInputStream(fo.getBytes()));
+ Result res = new SAXResult(fop.getDefaultHandler());
+
+ try {
+ transformer.transform(src, res);
+ } finally {
+ out.close();
+ }
+
+ try (PDDocument pdfDocument = Loader.loadPDF(out.toByteArray())) {
+ PDFMarkedContentExtractor extractor = new PDFMarkedContentExtractor();
+ assertEquals(2, pdfDocument.getPages().getCount());
+ extractor.processPage(pdfDocument.getPages().get(0));
+ extractor.processPage(pdfDocument.getPages().get(1));
+
+ List markedContents = extractor.getMarkedContents();
+ assertEquals(4, markedContents.size());
+
+ assertEquals("Artifact", markedContents.get(0).getTag());
+ assertEquals("1", markedContents.get(0).getContents().get(0).toString());
+
+ assertEquals("P", markedContents.get(1).getTag());
+ assertEquals("A", markedContents.get(1).getContents().get(0).toString());
+
+ assertEquals("Artifact", markedContents.get(2).getTag());
+ assertEquals("2", markedContents.get(2).getContents().get(0).toString());
+
+ assertEquals("P", markedContents.get(3).getTag());
+ assertEquals("B", markedContents.get(3).getContents().get(0).toString());
+ }
+ }
+
private void compare(final String fo, String tree) throws Exception {
foLoader = new FOLoader("") {
public InputStream getFoInputStream() {