]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
FOP #2234: NPE when rendering a document with markers and accessibility is enabled
authorVincent Hennebert <vhennebert@apache.org>
Mon, 8 Apr 2013 11:51:52 +0000 (11:51 +0000)
committerVincent Hennebert <vhennebert@apache.org>
Mon, 8 Apr 2013 11:51:52 +0000 (11:51 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1465599 13f79535-47bb-0310-9956-ffa450edef68

87 files changed:
src/java/org/apache/fop/accessibility/DummyStructureTreeEventHandler.java
src/java/org/apache/fop/accessibility/StructureTree2SAXEventAdapter.java
src/java/org/apache/fop/accessibility/StructureTreeEventHandler.java
src/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java
src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java
src/java/org/apache/fop/fo/DelegatingFOEventHandler.java
src/java/org/apache/fop/fo/FOEventHandler.java
src/java/org/apache/fop/fo/FONode.java
src/java/org/apache/fop/fo/FOText.java
src/java/org/apache/fop/fo/FOTreeBuilder.java
src/java/org/apache/fop/fo/FObj.java
src/java/org/apache/fop/fo/FObjMixed.java
src/java/org/apache/fop/fo/extensions/ExternalDocument.java
src/java/org/apache/fop/fo/extensions/destination/Destination.java
src/java/org/apache/fop/fo/flow/AbstractGraphics.java
src/java/org/apache/fop/fo/flow/AbstractListItemPart.java
src/java/org/apache/fop/fo/flow/AbstractPageNumberCitation.java
src/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java
src/java/org/apache/fop/fo/flow/BasicLink.java
src/java/org/apache/fop/fo/flow/Block.java
src/java/org/apache/fop/fo/flow/BlockContainer.java
src/java/org/apache/fop/fo/flow/Character.java
src/java/org/apache/fop/fo/flow/ExternalGraphic.java
src/java/org/apache/fop/fo/flow/Float.java
src/java/org/apache/fop/fo/flow/Footnote.java
src/java/org/apache/fop/fo/flow/FootnoteBody.java
src/java/org/apache/fop/fo/flow/Inline.java
src/java/org/apache/fop/fo/flow/InlineContainer.java
src/java/org/apache/fop/fo/flow/InstreamForeignObject.java
src/java/org/apache/fop/fo/flow/Leader.java
src/java/org/apache/fop/fo/flow/ListBlock.java
src/java/org/apache/fop/fo/flow/ListItem.java
src/java/org/apache/fop/fo/flow/ListItemBody.java
src/java/org/apache/fop/fo/flow/ListItemLabel.java
src/java/org/apache/fop/fo/flow/Marker.java
src/java/org/apache/fop/fo/flow/MultiProperties.java
src/java/org/apache/fop/fo/flow/MultiSwitch.java
src/java/org/apache/fop/fo/flow/PageNumber.java
src/java/org/apache/fop/fo/flow/PageNumberCitation.java
src/java/org/apache/fop/fo/flow/PageNumberCitationLast.java
src/java/org/apache/fop/fo/flow/RetrieveMarker.java
src/java/org/apache/fop/fo/flow/RetrieveTableMarker.java
src/java/org/apache/fop/fo/flow/Wrapper.java
src/java/org/apache/fop/fo/flow/table/Table.java
src/java/org/apache/fop/fo/flow/table/TableAndCaption.java
src/java/org/apache/fop/fo/flow/table/TableBody.java
src/java/org/apache/fop/fo/flow/table/TableCaption.java
src/java/org/apache/fop/fo/flow/table/TableCell.java
src/java/org/apache/fop/fo/flow/table/TableFooter.java
src/java/org/apache/fop/fo/flow/table/TableHeader.java
src/java/org/apache/fop/fo/flow/table/TableRow.java
src/java/org/apache/fop/fo/pagination/AbstractPageSequence.java
src/java/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java
src/java/org/apache/fop/fo/pagination/Declarations.java
src/java/org/apache/fop/fo/pagination/Flow.java
src/java/org/apache/fop/fo/pagination/LayoutMasterSet.java
src/java/org/apache/fop/fo/pagination/PageSequence.java
src/java/org/apache/fop/fo/pagination/PageSequenceMaster.java
src/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java
src/java/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java
src/java/org/apache/fop/fo/pagination/Root.java
src/java/org/apache/fop/fo/pagination/SimplePageMaster.java
src/java/org/apache/fop/fo/pagination/SinglePageMasterReference.java
src/java/org/apache/fop/fo/pagination/StaticContent.java
src/java/org/apache/fop/fo/pagination/bookmarks/Bookmark.java
src/java/org/apache/fop/fo/pagination/bookmarks/BookmarkTree.java
src/java/org/apache/fop/pdf/PDFStructElem.java
src/java/org/apache/fop/render/afp/extensions/AFPIncludeFormMapElement.java
src/java/org/apache/fop/render/afp/extensions/AFPInvokeMediumMapElement.java
src/java/org/apache/fop/render/afp/extensions/AFPPageOverlayElement.java
src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java
src/java/org/apache/fop/render/afp/extensions/AbstractAFPExtensionObject.java
src/java/org/apache/fop/render/intermediate/IFParser.java
src/java/org/apache/fop/render/intermediate/IFSerializer.java
src/java/org/apache/fop/render/intermediate/IFStructureTreeBuilder.java
src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java
src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java
src/java/org/apache/fop/render/pdf/extensions/PDFEmbeddedFileElement.java
src/java/org/apache/fop/render/ps/extensions/AbstractPSCommentElement.java
src/java/org/apache/fop/render/ps/extensions/AbstractPSExtensionElement.java
src/java/org/apache/fop/render/ps/extensions/AbstractPSExtensionObject.java
src/java/org/apache/fop/render/ps/extensions/PSPageSetupCodeElement.java
src/java/org/apache/fop/render/ps/extensions/PSSetPageDeviceElement.java
src/java/org/apache/fop/render/ps/extensions/PSSetupCodeElement.java
test/java/org/apache/fop/render/intermediate/IFStructureTreeBuilderTestCase.java
test/pdf/accessibility/markers.fo [new file with mode: 0644]
test/pdf/accessibility/pdf/markers.pdf [new file with mode: 0644]

index c63c721e5169a915f3d9dc16c27bb14abcdb5013..be11776354e445d1cd3a7130742d167def74c7ca 100644 (file)
@@ -42,7 +42,7 @@ public final class DummyStructureTreeEventHandler implements StructureTreeEventH
     }
 
     /** {@inheritDoc} */
-    public StructureTreeElement startNode(String name, Attributes attributes) {
+    public StructureTreeElement startNode(String name, Attributes attributes, StructureTreeElement parent) {
         return null;
     }
 
@@ -51,12 +51,12 @@ public final class DummyStructureTreeEventHandler implements StructureTreeEventH
     }
 
     /** {@inheritDoc} */
-    public StructureTreeElement startImageNode(String name, Attributes attributes) {
+    public StructureTreeElement startImageNode(String name, Attributes attributes, StructureTreeElement parent) {
         return null;
     }
 
     /** {@inheritDoc} */
-    public StructureTreeElement startReferencedNode(String name, Attributes attributes) {
+    public StructureTreeElement startReferencedNode(String name, Attributes attributes, StructureTreeElement parent) {
         return null;
     }
 
index 7a375ef2002771270ec01bd34981811c618b6929..0b8073e57204fbaadbf5214796da19f83f24d6eb 100644 (file)
@@ -87,7 +87,7 @@ public final class StructureTree2SAXEventAdapter implements StructureTreeEventHa
     }
 
     /** {@inheritDoc} */
-    public StructureTreeElement startNode(String name, Attributes attributes) {
+    public StructureTreeElement startNode(String name, Attributes attributes, StructureTreeElement parent) {
         try {
             if (name.equals("#PCDATA")) {
                 name = "marked-content";
@@ -115,13 +115,13 @@ public final class StructureTree2SAXEventAdapter implements StructureTreeEventHa
     }
 
     /** {@inheritDoc} */
-    public StructureTreeElement startImageNode(String name, Attributes attributes) {
-        return startNode(name, attributes);
+    public StructureTreeElement startImageNode(String name, Attributes attributes, StructureTreeElement parent) {
+        return startNode(name, attributes, null);
     }
 
     /** {@inheritDoc} */
-    public StructureTreeElement startReferencedNode(String name, Attributes attributes) {
-        return startNode(name, attributes);
+    public StructureTreeElement startReferencedNode(String name, Attributes attributes, StructureTreeElement parent) {
+        return startNode(name, attributes, null);
     }
 
 }
index 46b724626eb387614c24c8f90260bdc01558d693..53c27130c684dae6467ce71597b781cc2e795143 100644 (file)
@@ -43,9 +43,11 @@ public interface StructureTreeEventHandler {
      *
      * @param name the name of the structure tree node
      * @param attributes the node properties
+     * @param parent the parent of the node. May be null, in which case the parent node is
+     * the node corresponding to the previous call to this method
      * @return the corresponding structure tree element
      */
-    StructureTreeElement startNode(String name, Attributes attributes);
+    StructureTreeElement startNode(String name, Attributes attributes, StructureTreeElement parent);
 
     /**
      * Ends a structure tree node.
@@ -59,9 +61,11 @@ public interface StructureTreeEventHandler {
      *
      * @param name the name of the structure tree node
      * @param attributes the node properties
+     * @param parent the parent of the node. May be null, in which case the parent node is
+     * the node corresponding to the previous call to this method
      * @return the corresponding structure tree element
      */
-    StructureTreeElement startImageNode(String name, Attributes attributes);
+    StructureTreeElement startImageNode(String name, Attributes attributes, StructureTreeElement parent);
 
     /**
      * Starts a node that can be referenced by other nodes. This is usually a
@@ -69,9 +73,11 @@ public interface StructureTreeEventHandler {
      *
      * @param name the name of the structure tree node
      * @param attributes the node properties
+     * @param parent the parent of the node. May be null, in which case the parent node is
+     * the node corresponding to the previous call to this method
      * @return the corresponding structure tree element
      */
-    StructureTreeElement startReferencedNode(String name, Attributes attributes);
+    StructureTreeElement startReferencedNode(String name, Attributes attributes, StructureTreeElement parent);
 
     /**
      * Ends a page sequence structure tree node.
index aaf112cb50b659c4719596e19b0018afe05c310b..4614a7005e0494a62f02d6ba42cc1d24e32599e2 100644 (file)
@@ -19,6 +19,8 @@
 
 package org.apache.fop.accessibility.fo;
 
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Stack;
 
 import org.xml.sax.SAXException;
@@ -29,6 +31,7 @@ import org.apache.fop.fo.DelegatingFOEventHandler;
 import org.apache.fop.fo.FOEventHandler;
 import org.apache.fop.fo.FOText;
 import org.apache.fop.fo.extensions.ExternalDocument;
+import org.apache.fop.fo.flow.AbstractRetrieveMarker;
 import org.apache.fop.fo.flow.BasicLink;
 import org.apache.fop.fo.flow.Block;
 import org.apache.fop.fo.flow.BlockContainer;
@@ -46,6 +49,8 @@ import org.apache.fop.fo.flow.ListItemLabel;
 import org.apache.fop.fo.flow.PageNumber;
 import org.apache.fop.fo.flow.PageNumberCitation;
 import org.apache.fop.fo.flow.PageNumberCitationLast;
+import org.apache.fop.fo.flow.RetrieveMarker;
+import org.apache.fop.fo.flow.RetrieveTableMarker;
 import org.apache.fop.fo.flow.Wrapper;
 import org.apache.fop.fo.flow.table.Table;
 import org.apache.fop.fo.flow.table.TableBody;
@@ -70,14 +75,30 @@ public class FO2StructureTreeConverter extends DelegatingFOEventHandler {
     /** The top of the {@link converters} stack. */
     private FOEventHandler converter;
 
-    private final Stack<FOEventHandler> converters = new Stack<FOEventHandler>();
+    private Stack<FOEventHandler> converters = new Stack<FOEventHandler>();
 
-    private final FOEventHandler structureTreeEventTrigger;
+    private final StructureTreeEventTrigger structureTreeEventTrigger;
 
     /** The descendants of some elements like fo:leader must be ignored. */
     private final FOEventHandler eventSwallower = new FOEventHandler() {
     };
 
+    private final Map<AbstractRetrieveMarker, State> states = new HashMap<AbstractRetrieveMarker, State>();
+
+    private static final class State {
+
+        private final FOEventHandler converter;
+
+        private final Stack<FOEventHandler> converters;
+
+        @SuppressWarnings("unchecked")
+        State(FO2StructureTreeConverter o) {
+            this.converter = o.converter;
+            this.converters = (Stack<FOEventHandler>) o.converters.clone();
+        }
+
+    }
+
     /**
      * Creates a new instance.
      *
@@ -458,6 +479,57 @@ public class FO2StructureTreeConverter extends DelegatingFOEventHandler {
         super.endWrapper(wrapper);
     }
 
+    @Override
+    public void startRetrieveMarker(RetrieveMarker retrieveMarker) {
+        converter.startRetrieveMarker(retrieveMarker);
+        saveState(retrieveMarker);
+        super.startRetrieveMarker(retrieveMarker);
+    }
+
+    private void saveState(AbstractRetrieveMarker retrieveMarker) {
+        states.put(retrieveMarker, new State(this));
+    }
+
+    @Override
+    public void endRetrieveMarker(RetrieveMarker retrieveMarker) {
+        converter.endRetrieveMarker(retrieveMarker);
+        super.endRetrieveMarker(retrieveMarker);
+    }
+
+    @Override
+    public void restoreState(RetrieveMarker retrieveMarker) {
+        restoreRetrieveMarkerState(retrieveMarker);
+        converter.restoreState(retrieveMarker);
+        super.restoreState(retrieveMarker);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void restoreRetrieveMarkerState(AbstractRetrieveMarker retrieveMarker) {
+        State state = states.get(retrieveMarker);
+        this.converter = state.converter;
+        this.converters = (Stack<FOEventHandler>) state.converters.clone();
+    }
+
+    @Override
+    public void startRetrieveTableMarker(RetrieveTableMarker retrieveTableMarker) {
+        converter.startRetrieveTableMarker(retrieveTableMarker);
+        saveState(retrieveTableMarker);
+        super.startRetrieveTableMarker(retrieveTableMarker);
+    }
+
+    @Override
+    public void endRetrieveTableMarker(RetrieveTableMarker retrieveTableMarker) {
+        converter.endRetrieveTableMarker(retrieveTableMarker);
+        super.endRetrieveTableMarker(retrieveTableMarker);
+    }
+
+    @Override
+    public void restoreState(RetrieveTableMarker retrieveTableMarker) {
+        restoreRetrieveMarkerState(retrieveTableMarker);
+        converter.restoreState(retrieveTableMarker);
+        super.restoreState(retrieveTableMarker);
+    }
+
     @Override
     public void character(Character c) {
         converter.character(c);
index 6a763a6f67c6f8c1e33ff5f8fc30fbddc160ff32..1a59bebfb6a75bbb8ad284577326083aa0b25e89 100644 (file)
@@ -19,7 +19,9 @@
 
 package org.apache.fop.accessibility.fo;
 
+import java.util.HashMap;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Stack;
 
 import javax.xml.XMLConstants;
@@ -34,6 +36,7 @@ import org.apache.fop.fo.FOText;
 import org.apache.fop.fo.extensions.ExtensionElementMapping;
 import org.apache.fop.fo.extensions.InternalElementMapping;
 import org.apache.fop.fo.flow.AbstractGraphics;
+import org.apache.fop.fo.flow.AbstractRetrieveMarker;
 import org.apache.fop.fo.flow.BasicLink;
 import org.apache.fop.fo.flow.Block;
 import org.apache.fop.fo.flow.BlockContainer;
@@ -50,6 +53,8 @@ import org.apache.fop.fo.flow.ListItemLabel;
 import org.apache.fop.fo.flow.PageNumber;
 import org.apache.fop.fo.flow.PageNumberCitation;
 import org.apache.fop.fo.flow.PageNumberCitationLast;
+import org.apache.fop.fo.flow.RetrieveMarker;
+import org.apache.fop.fo.flow.RetrieveTableMarker;
 import org.apache.fop.fo.flow.Wrapper;
 import org.apache.fop.fo.flow.table.Table;
 import org.apache.fop.fo.flow.table.TableBody;
@@ -76,11 +81,30 @@ class StructureTreeEventTrigger extends FOEventHandler {
 
     private LayoutMasterSet layoutMasterSet;
 
-    private final Stack<Table> tables = new Stack<Table>();
+    private Stack<Table> tables = new Stack<Table>();
 
-    private final Stack<Boolean> inTableHeader = new Stack<Boolean>();
+    private Stack<Boolean> inTableHeader = new Stack<Boolean>();
 
-    private final Stack<Locale> locales = new Stack<Locale>();
+    private Stack<Locale> locales = new Stack<Locale>();
+
+    private final Map<AbstractRetrieveMarker, State> states = new HashMap<AbstractRetrieveMarker, State>();
+
+    private static final class State {
+
+        private final Stack<Table> tables;
+
+        private final Stack<Boolean> inTableHeader;
+
+        private final Stack<Locale> locales;
+
+        @SuppressWarnings("unchecked")
+        State(StructureTreeEventTrigger o) {
+            this.tables = (Stack<Table>) o.tables.clone();
+            this.inTableHeader = (Stack<Boolean>) o.inTableHeader.clone();
+            this.locales = (Stack<Locale>) o.locales.clone();
+        }
+
+    }
 
     public StructureTreeEventTrigger(StructureTreeEventHandler structureTreeEventHandler) {
         this.structureTreeEventHandler = structureTreeEventHandler;
@@ -414,6 +438,50 @@ class StructureTreeEventTrigger extends FOEventHandler {
         endElement(wrapper);
     }
 
+    @Override
+    public void startRetrieveMarker(RetrieveMarker retrieveMarker) {
+        startElementWithID(retrieveMarker);
+        saveState(retrieveMarker);
+    }
+
+    void saveState(AbstractRetrieveMarker retrieveMarker) {
+        states.put(retrieveMarker, new State(this));
+    }
+
+    @Override
+    public void endRetrieveMarker(RetrieveMarker retrieveMarker) {
+        endElement(retrieveMarker);
+    }
+
+    @Override
+    public void restoreState(RetrieveMarker retrieveMarker) {
+        restoreRetrieveMarkerState(retrieveMarker);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void restoreRetrieveMarkerState(AbstractRetrieveMarker retrieveMarker) {
+        State state = states.get(retrieveMarker);
+        tables = (Stack<Table>) state.tables.clone();
+        inTableHeader = (Stack<Boolean>) state.inTableHeader.clone();
+        locales = (Stack<Locale>) state.locales.clone();
+    }
+
+    @Override
+    public void startRetrieveTableMarker(RetrieveTableMarker retrieveTableMarker) {
+        startElementWithID(retrieveTableMarker);
+        saveState(retrieveTableMarker);
+    }
+
+    @Override
+    public void endRetrieveTableMarker(RetrieveTableMarker retrieveTableMarker) {
+        endElement(retrieveTableMarker);
+    }
+
+    @Override
+    public void restoreState(RetrieveTableMarker retrieveTableMarker) {
+        restoreRetrieveMarkerState(retrieveTableMarker);
+    }
+
     @Override
     public void character(Character c) {
         AttributesImpl attributes = createLangAttribute(c.getCommonHyphenation());
@@ -429,8 +497,8 @@ class StructureTreeEventTrigger extends FOEventHandler {
     }
 
 
-    private void startElement(FONode node) {
-        startElement(node, new AttributesImpl());
+    private StructureTreeElement startElement(FONode node) {
+        return startElement(node, new AttributesImpl());
     }
 
     private void startElementWithID(FONode node) {
@@ -443,7 +511,8 @@ class StructureTreeEventTrigger extends FOEventHandler {
             addRole((CommonAccessibilityHolder) node, attributes);
         }
         node.setStructureTreeElement(
-                structureTreeEventHandler.startReferencedNode(localName, attributes));
+                structureTreeEventHandler.startReferencedNode(localName, attributes,
+                        node.getParent().getStructureTreeElement()));
     }
 
     private void startElementWithIDAndAltText(AbstractGraphics node) {
@@ -453,7 +522,8 @@ class StructureTreeEventTrigger extends FOEventHandler {
         addAttribute(attributes, ExtensionElementMapping.URI, "alt-text",
                 ExtensionElementMapping.STANDARD_PREFIX, node.getAltText());
         node.setStructureTreeElement(
-                structureTreeEventHandler.startImageNode(localName, attributes));
+                structureTreeEventHandler.startImageNode(localName, attributes,
+                        node.getParent().getStructureTreeElement()));
     }
 
     private StructureTreeElement startElement(FONode node, AttributesImpl attributes) {
@@ -461,7 +531,8 @@ class StructureTreeEventTrigger extends FOEventHandler {
         if (node instanceof CommonAccessibilityHolder) {
             addRole((CommonAccessibilityHolder) node, attributes);
         }
-        return structureTreeEventHandler.startNode(localName, attributes);
+        return structureTreeEventHandler.startNode(localName, attributes,
+                node.getParent().getStructureTreeElement());
     }
 
     private void addNoNamespaceAttribute(AttributesImpl attributes, String name, String value) {
index bb0a1ba752023669d5fdd2a4436ad631367ddc9f..4cf6ddd1577960d63a222c98baef01557d6bbac5 100644 (file)
@@ -41,6 +41,8 @@ import org.apache.fop.fo.flow.ListItemLabel;
 import org.apache.fop.fo.flow.PageNumber;
 import org.apache.fop.fo.flow.PageNumberCitation;
 import org.apache.fop.fo.flow.PageNumberCitationLast;
+import org.apache.fop.fo.flow.RetrieveMarker;
+import org.apache.fop.fo.flow.RetrieveTableMarker;
 import org.apache.fop.fo.flow.Wrapper;
 import org.apache.fop.fo.flow.table.Table;
 import org.apache.fop.fo.flow.table.TableBody;
@@ -382,6 +384,36 @@ public abstract class DelegatingFOEventHandler extends FOEventHandler {
         delegate.endWrapper(wrapper);
     }
 
+    @Override
+    public void startRetrieveMarker(RetrieveMarker retrieveMarker) {
+        delegate.startRetrieveMarker(retrieveMarker);
+    }
+
+    @Override
+    public void endRetrieveMarker(RetrieveMarker retrieveMarker) {
+        delegate.endRetrieveMarker(retrieveMarker);
+    }
+
+    @Override
+    public void restoreState(RetrieveMarker retrieveMarker) {
+        delegate.restoreState(retrieveMarker);
+    }
+
+    @Override
+    public void startRetrieveTableMarker(RetrieveTableMarker retrieveTableMarker) {
+        delegate.startRetrieveTableMarker(retrieveTableMarker);
+    }
+
+    @Override
+    public void endRetrieveTableMarker(RetrieveTableMarker retrieveTableMarker) {
+        delegate.endRetrieveTableMarker(retrieveTableMarker);
+    }
+
+    @Override
+    public void restoreState(RetrieveTableMarker retrieveTableMarker) {
+        delegate.restoreState(retrieveTableMarker);
+    }
+
     @Override
     public void character(Character c) {
         delegate.character(c);
index ad647e42a3321c9dcbaa778d941ead4332c2fbc9..0be90dd04bfe4657dc5aad5feb089a689ba7204e 100644 (file)
@@ -41,6 +41,8 @@ import org.apache.fop.fo.flow.ListItemLabel;
 import org.apache.fop.fo.flow.PageNumber;
 import org.apache.fop.fo.flow.PageNumberCitation;
 import org.apache.fop.fo.flow.PageNumberCitationLast;
+import org.apache.fop.fo.flow.RetrieveMarker;
+import org.apache.fop.fo.flow.RetrieveTableMarker;
 import org.apache.fop.fo.flow.Wrapper;
 import org.apache.fop.fo.flow.table.Table;
 import org.apache.fop.fo.flow.table.TableBody;
@@ -534,6 +536,56 @@ public abstract class FOEventHandler {
     public void endWrapper(Wrapper wrapper) {
     }
 
+    /**
+     * Process the start of a retrieve-marker.
+     *
+     * @param retrieveMarker the retrieve-marker that is starting
+     */
+    public void startRetrieveMarker(RetrieveMarker retrieveMarker) {
+    }
+
+
+    /**
+     * Process the ending of a retrieve-marker.
+     *
+     * @param retrieveMarker the retrieve-marker that is ending
+     */
+    public void endRetrieveMarker(RetrieveMarker retrieveMarker) {
+    }
+
+    /**
+     * Restore the state of this event handler as it was when the given fo:retrieve-marker
+     * element was processed. This method is called at marker retrieval time, so that
+     * events for the marker descendants are fired within the proper context.
+     * <p>The default implementation of this method does nothing.</p>
+     *
+     * @param retrieveMarker the fo:retrieve-marker element that is retrieving markers
+     */
+    public void restoreState(RetrieveMarker retrieveMarker) {
+    }
+
+    /**
+     * Process the start of a retrieve-table-marker.
+     *
+     * @param retrieveTableMarker the retrieve-table-marker that is starting
+     */
+    public void startRetrieveTableMarker(RetrieveTableMarker retrieveTableMarker) {
+    }
+
+    /**
+     * Process the ending of a retrieve-table-marker.
+     *
+     * @param retrieveTableMarker the retrieve-table-marker that is ending
+     */
+    public void endRetrieveTableMarker(RetrieveTableMarker retrieveTableMarker) {
+    }
+
+    /**
+     * See {@link #restoreState(RetrieveMarker)}.
+     */
+    public void restoreState(RetrieveTableMarker retrieveTableMarker) {
+    }
+
     /**
      * Process a Character.
      * @param c Character to process.
index 2fae054fede9e797619a1312e1301abd1d8888ec..c9fd7e59a2d8d2a6ac35b0380db5ac08da4a0bdf 100644 (file)
@@ -311,7 +311,7 @@ public abstract class FONode implements Cloneable {
      *
      * @throws FOPException if there's a problem during processing
      */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         // do nothing by default
    }
 
@@ -327,7 +327,7 @@ public abstract class FONode implements Cloneable {
      *
      * @throws FOPException if there's a problem during processing
      */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         this.finalizeNode();
     }
 
@@ -1093,4 +1093,13 @@ public abstract class FONode implements Cloneable {
         throw new UnsupportedOperationException();
     }
 
+    /**
+     * Returns the structure tree element associated to this object.
+     *
+     * @return the structure tree element
+     */
+    public StructureTreeElement getStructureTreeElement() {
+        return null;
+    }
+
 }
index 5dfe0766be3758e5970fb9e34194f38df1dc702d..6806d752d472db065061416ba5dc5be507b63f61 100644 (file)
@@ -193,7 +193,7 @@ public class FOText extends FONode implements CharSequence {
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if ( charBuffer != null ) {
             charBuffer.rewind();
         }
@@ -726,7 +726,7 @@ public class FOText extends FONode implements CharSequence {
         this.structureTreeElement = structureTreeElement;
     }
 
-    /** @return the structure tree element. */
+    @Override
     public StructureTreeElement getStructureTreeElement() {
         return structureTreeElement;
     }
index 9040c464a147883b7c02bf51286fa2284a3299dd..84d03db83edad08d17686ff1f5c1d92f3b94f577 100644 (file)
@@ -321,7 +321,8 @@ public class FOTreeBuilder extends DefaultHandler {
             // fo:characters can potentially be removed during
             // white-space handling.
             // Do not notify the FOEventHandler.
-            if (currentFObj.getNameId() != Constants.FO_CHARACTER) {
+            if (currentFObj.getNameId() != Constants.FO_CHARACTER
+                    && (!builderContext.inMarker() || currentFObj.getNameId() == Constants.FO_MARKER)) {
                 currentFObj.startOfNode();
             }
         }
@@ -343,7 +344,8 @@ public class FOTreeBuilder extends DefaultHandler {
             // fo:characters can potentially be removed during
             // white-space handling.
             // Do not notify the FOEventHandler.
-            if (currentFObj.getNameId() != Constants.FO_CHARACTER) {
+            if (currentFObj.getNameId() != Constants.FO_CHARACTER
+                    && (!builderContext.inMarker() || currentFObj.getNameId() == Constants.FO_MARKER)) {
                 currentFObj.endOfNode();
             }
 
index a316a22603b4f126d709c1d39392b84efaffe74d..e7b4fc2e95580a8c693d3c162aba26eba1fa0fb2 100644 (file)
@@ -179,7 +179,7 @@ public abstract class FObj extends FONode implements Constants {
      * {@inheritDoc}
      * @throws FOPException FOP Exception
      */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         if (id != null) {
             checkId(id);
         }
index e582e8689c9083d4b0aade2608082a7e96ab86d1..f0a4e2695e391ad6c830a55ba7b5137c68b8f9a5 100644 (file)
@@ -49,6 +49,16 @@ public abstract class FObjMixed extends FObj {
         super(parent);
     }
 
+    @Override
+    public FONode clone(FONode parent, boolean removeChildren) throws FOPException {
+        flushText();
+        FObjMixed clone = (FObjMixed) super.clone(parent, removeChildren);
+        if (removeChildren) {
+            clone.currentTextNode = null;
+        }
+        return clone;
+    }
+
     /** {@inheritDoc} */
     @Override
     protected void characters(char[] data, int start, int length,
@@ -66,7 +76,7 @@ public abstract class FObjMixed extends FObj {
 
     /** {@inheritDoc} */
     @Override
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
 
         super.endOfNode();
         if (!inMarker() || getNameId() == FO_MARKER) {
index a6f5e768031b1259a2e080fca352a06c847baf53..b450c21ce73ea85bcdb5ccd8f3fbd2fee8c045d9 100644 (file)
@@ -86,7 +86,7 @@ public class ExternalDocument extends AbstractPageSequence implements GraphicsPr
      * @throws FOPException in case of processing exception
      * @see org.apache.fop.fo.FONode#startOfNode()
      */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startExternalDocument(this);
     }
@@ -95,7 +95,7 @@ public class ExternalDocument extends AbstractPageSequence implements GraphicsPr
      * @throws FOPException in case of processing exception
      * @see org.apache.fop.fo.FONode#endOfNode()
      */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         getFOEventHandler().endExternalDocument(this);
         super.endOfNode();
     }
index 98114bb23d8befeb1a81f6b915f32c555047837f..95ae64c7dd34e7aa751d2c9b4b6b2bc4aa25a1a8 100644 (file)
@@ -61,7 +61,7 @@ public class Destination extends FONode {
     /**
      * {@inheritDoc}
      */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         root.addDestination(this);
     }
 
index 3d93eaa8fac099427a0639fd41799bf12ed413e8..2bf0061b01a6df3ccda85e231d2651eeccb36116 100644 (file)
@@ -234,7 +234,7 @@ public abstract class AbstractGraphics extends FObj
         this.structureTreeElement = structureTreeElement;
     }
 
-    /** {@inheritDoc} */
+    @Override
     public StructureTreeElement getStructureTreeElement() {
         return structureTreeElement;
     }
index 0e99bfe96bdd7786e9f9ddeb78948d69bb4fedfe..c8e8fc62023072d99472cae9d835141dd50d79ad 100644 (file)
@@ -83,7 +83,7 @@ public abstract class AbstractListItemPart extends FObj implements CommonAccessi
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (!this.blockItemFound) {
             String contentModel = "marker* (%block;)+";
             getFOValidationEventProducer().missingChildElement(this, getName(),
index ec38916325401de2816d848124fc434073992d14..68582a430cfc36ca387f874e40c471e2946d0a54 100644 (file)
@@ -160,7 +160,7 @@ public abstract class AbstractPageNumberCitation extends FObj
         this.structureTreeElement = structureTreeElement;
     }
 
-    /** {@inheritDoc} */
+    @Override
     public StructureTreeElement getStructureTreeElement() {
         return structureTreeElement;
     }
index 636bc04df7d0c48b9048f04667ec54c95a5f09b2..018f6bb7308aaf21cec15e7165a4aff84f7222f6 100644 (file)
@@ -23,6 +23,7 @@ import java.util.Iterator;
 
 import org.xml.sax.Locator;
 
+import org.apache.fop.accessibility.StructureTreeElement;
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.FOText;
@@ -51,6 +52,8 @@ public abstract class AbstractRetrieveMarker extends FObjMixed {
     private int boundary;
     private String boundaryLabel;
 
+    private StructureTreeElement structureTreeElement;
+
     /**
      * Create a new AbstractRetrieveMarker instance that
      * is a child of the given {@link FONode}
@@ -86,6 +89,16 @@ public abstract class AbstractRetrieveMarker extends FObjMixed {
         this.propertyList = pList.getParentPropertyList();
     }
 
+    @Override
+    public void setStructureTreeElement(StructureTreeElement structureTreeElement) {
+        this.structureTreeElement = structureTreeElement;
+    }
+
+    @Override
+    public StructureTreeElement getStructureTreeElement() {
+        return structureTreeElement;
+    }
+
     private PropertyList createPropertyListFor(FObj fo, PropertyList parent) {
         return getBuilderContext().getPropertyListMaker().make(fo, parent);
     }
@@ -108,6 +121,7 @@ public abstract class AbstractRetrieveMarker extends FObjMixed {
                         pList,
                         newPropertyList);
                 addChildTo(newChild, newParent);
+                newChild.startOfNode();
                 switch ( newChild.getNameId() ) {
                 case FO_TABLE:
                     Table t = (Table) child;
@@ -132,17 +146,22 @@ public abstract class AbstractRetrieveMarker extends FObjMixed {
                                     newChild, marker, newPropertyList);
                     break;
                 }
+                newChild.endOfNode();
             } else if (child instanceof FOText) {
                 FOText ft = (FOText) newChild;
                 ft.bind(parentPropertyList);
                 addChildTo(newChild, newParent);
+                if (newParent instanceof AbstractRetrieveMarker) {
+                    /*
+                     * Otherwise the parent of newChild is a cloned FObjMixed that will
+                     * call this FOText's endOfNode when its own endOfNode method is
+                     * called.
+                     */
+                    newChild.endOfNode();
+                }
             } else if (child instanceof XMLObj) {
                 addChildTo(newChild, newParent);
             }
-
-            // trigger end-of-node white-space handling
-            // and finalization for table-FOs
-            newChild.finalizeNode();
         }
     }
 
@@ -191,6 +210,7 @@ public abstract class AbstractRetrieveMarker extends FObjMixed {
         }
         if (marker.getChildNodes() != null) {
             try {
+                restoreFOEventHandlerState();
                 cloneFromMarker(marker);
             } catch (FOPException exc) {
                 getFOValidationEventProducer().markerCloningFailed(this,
@@ -201,6 +221,8 @@ public abstract class AbstractRetrieveMarker extends FObjMixed {
         }
     }
 
+    protected abstract void restoreFOEventHandlerState();
+
     /**
      * Return the value for the <code>retrieve-class-name</code>
      * property
index 0d6d5d9b4c545a0a6ff89df1a55ae4958c403881..3394842fb003b7082e839024342e918e5587d03d 100644 (file)
@@ -96,13 +96,13 @@ public class BasicLink extends InlineLevel implements StructureTreeElementHolder
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startLink(this);
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         getFOEventHandler().endLink(this);
     }
@@ -148,7 +148,7 @@ public class BasicLink extends InlineLevel implements StructureTreeElementHolder
         this.structureTreeElement = structureTreeElement;
     }
 
-    /** {@inheritDoc} */
+    @Override
     public StructureTreeElement getStructureTreeElement() {
         return structureTreeElement;
     }
index d93821ca6a80db6f38f52cc8cc50883aec6af9bf..13b218b5573688c4b87c9877a5a570a57cd434b8 100644 (file)
@@ -140,13 +140,13 @@ public class Block extends FObjMixed implements BreakPropertySet,
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startBlock(this);
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         getFOEventHandler().endBlock(this);
     }
index cdeb990815d6d401fd4a2f93fcc79add025fb92c..005f9289a9a0dc04e083f14e75ec6a6b1736054a 100644 (file)
@@ -103,7 +103,7 @@ public class BlockContainer extends FObj implements BreakPropertySet, WritingMod
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startBlockContainer(this);
     }
@@ -138,7 +138,7 @@ public class BlockContainer extends FObj implements BreakPropertySet, WritingMod
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (!blockItemFound) {
             missingChildElementError("marker* (%block;)+");
         }
index f48ff289e0835d1e5e2e4ac42d2476e4a6b0d600..2d081430161fd00ea5ace0bc9825c1f366d8821d 100644 (file)
@@ -116,7 +116,7 @@ public class Character extends FObj implements StructureTreeElementHolder {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().character(this);
     }
@@ -217,7 +217,7 @@ public class Character extends FObj implements StructureTreeElementHolder {
         this.structureTreeElement = structureTreeElement;
     }
 
-    /** {@inheritDoc} */
+    @Override
     public StructureTreeElement getStructureTreeElement() {
         return structureTreeElement;
     }
index dc8584abc071009f54a63bf3c47628339366a158..b564526b48c7a1290a3e88832d0f7d3153cde002 100644 (file)
@@ -104,7 +104,7 @@ public class ExternalGraphic extends AbstractGraphics {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().image(this);
     }
index 5d8fcdc2cd11f038eb148b9d493f267450f8ad7c..c12998144bb237d15f57225c961f1df410ff9204 100644 (file)
@@ -74,7 +74,7 @@ public class Float extends FObj {
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (firstChild == null) {
             missingChildElementError("(%block;)+");
         }
index 5953363ed8b3d6821ad37156dde64f5ecc90d20f..3aa2097a200f52f8e04c8a095968f9ed0e5f3aaa 100644 (file)
@@ -56,7 +56,7 @@ public class Footnote extends FObj implements CommonAccessibilityHolder {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         getFOEventHandler().startFootnote(this);
     }
 
@@ -66,7 +66,7 @@ public class Footnote extends FObj implements CommonAccessibilityHolder {
      *
      * {@inheritDoc}
      */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         if (footnoteCitation == null || footnoteBody == null) {
             missingChildElementError("(inline,footnote-body)");
index 1c103b6b5da080ba7e82c0ea17012d43a6bb4329..af2bc2bcf57e334b7e38149665bea2b6a6169018 100644 (file)
@@ -54,7 +54,7 @@ public class FootnoteBody extends FObj implements CommonAccessibilityHolder {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         getFOEventHandler().startFootnoteBody(this);
     }
 
@@ -64,7 +64,7 @@ public class FootnoteBody extends FObj implements CommonAccessibilityHolder {
      * end of the footnote-body.
      * {@inheritDoc}
      */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (firstChild == null) {
             missingChildElementError("(%block;)+");
         }
index 941850cdd967a9ec35c536941b704c13e53a417a..d115f469a33385423d912969c5e9957b5d7f4bf6 100644 (file)
@@ -69,7 +69,7 @@ public class Inline extends InlineLevel {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
        super.startOfNode();
 
        /* Check to see if this node can have block-level children.
@@ -94,7 +94,7 @@ public class Inline extends InlineLevel {
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         getFOEventHandler().endInline(this);
     }
index b79d66bb094388324fa5cb033c231a74bf1ae6de..b8e9fd09a6d08bb6615f1870e1ab30b615f15117 100644 (file)
@@ -119,7 +119,7 @@ public class InlineContainer extends FObj {
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (!blockItemFound) {
             missingChildElementError("marker* (%block;)+");
         }
index 33164188fde56f6dd2837533f9167c6c47491e70..9f88b94784d31987cb636f62c01b44cc5d0c12e0 100644 (file)
@@ -60,7 +60,7 @@ public class InstreamForeignObject extends AbstractGraphics {
     }
 
     @Override
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startInstreamForeignObject(this);
     }
@@ -71,7 +71,7 @@ public class InstreamForeignObject extends AbstractGraphics {
      * the end of the instream-foreign-object.
      * {@inheritDoc}
      */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (firstChild == null) {
             missingChildElementError("one (1) non-XSL namespace child");
         }
index 4062d65629a4501e127cefab924dcf1f27f34b5d..c1fd980029a3f2e8e8d6e608f8fd1b4789b7f1cf 100644 (file)
@@ -191,13 +191,13 @@ public class Leader extends InlineLevel {
     }
 
     @Override
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startLeader(this);
     }
 
     @Override
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         getFOEventHandler().endLeader(this);
     }
index 35288ec80e208960cb8f50c3c9b2474ca8e1152f..6478911312004264a045df70cca2d1b37c1aa54c 100644 (file)
@@ -89,7 +89,7 @@ public class ListBlock extends FObj implements BreakPropertySet, CommonAccessibi
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startList(this);
     }
@@ -100,7 +100,7 @@ public class ListBlock extends FObj implements BreakPropertySet, CommonAccessibi
      * of the list-block.
      * {@inheritDoc}
      */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (!hasListItem) {
             missingChildElementError("marker* (list-item)+");
         }
index f61254874f18ea4d234eae1a04d9e416c61942d4..bfd512f4db1d62a15fa7a7412455c8fda925a29a 100644 (file)
@@ -83,13 +83,13 @@ public class ListItem extends FObj implements BreakPropertySet, CommonAccessibil
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startListItem(this);
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (label == null || body == null) {
             missingChildElementError("marker* (list-item-label,list-item-body)");
         }
index 3007f9ba3b8bd32fbc20b8191f930923bfb9cef5..5b121f53c1d6a1e1521b120c75bad92de5b80912 100644 (file)
@@ -36,13 +36,13 @@ public class ListItemBody extends AbstractListItemPart {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startListBody(this);
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         getFOEventHandler().endListBody(this);
     }
index 10436afa6398023ee34a6db27ddb3096f60af6b9..53dfab84ee9acbc71d4fc73835fe82dabaa54159 100644 (file)
@@ -38,13 +38,13 @@ public class ListItemLabel extends AbstractListItemPart {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startListLabel(this);
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         getFOEventHandler().endListLabel(this);
     }
index de806e9865f20023c6e9435836f58441dee83825..5d525ee8cd387442c31f7f48b0010dd84f54fbb9 100644 (file)
@@ -83,7 +83,7 @@ public class Marker extends FObjMixed {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() {
+    public void startOfNode() {
         FOTreeBuilderContext builderContext = getBuilderContext();
         // Push a new property list maker which will make MarkerPropertyLists.
         savePropertyListMaker = builderContext.getPropertyListMaker();
@@ -97,7 +97,7 @@ public class Marker extends FObjMixed {
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         // Pop the MarkerPropertyList maker.
         getBuilderContext().setPropertyListMaker(savePropertyListMaker);
index 3e2e57d97e2afd925058f13682de53ac046ed4aa..ff819200651e76a6662916dc6777d573b273da37 100644 (file)
@@ -59,7 +59,7 @@ public class MultiProperties extends FObj {
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (!hasMultiPropertySet || !hasWrapper) {
             missingChildElementError("(multi-property-set+, wrapper)");
         }
index aa18d6cdfc1a34ed0614a0cfb0d07856d22b61cf..d8ebee4cba55e00b66ceaab598579eb89fcda0b0 100644 (file)
@@ -64,7 +64,7 @@ public class MultiSwitch extends FObj {
 
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (firstChild == null) {
             missingChildElementError("(multi-case+)");
         }
index fe3e80a7569f5c8a271eb8596782713df1259357..33b34e2d53bd9cfc79ce8445ba6b7fddf08e1461 100644 (file)
@@ -106,13 +106,13 @@ public class PageNumber extends FObj
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startPageNumber(this);
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         getFOEventHandler().endPageNumber(this);
     }
 
@@ -182,7 +182,7 @@ public class PageNumber extends FObj
         this.structureTreeElement = structureTreeElement;
     }
 
-    /** {@inheritDoc} */
+    @Override
     public StructureTreeElement getStructureTreeElement() {
         return structureTreeElement;
     }
index 0ebb6eb3dc161f248a86dca8282ace9c5a96a5a4..ee7b59a15595dfbb764873172e569e56d80be69b 100644 (file)
@@ -41,13 +41,13 @@ public class PageNumberCitation extends AbstractPageNumberCitation {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startPageNumberCitation(this);
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         getFOEventHandler().endPageNumberCitation(this);
     }
index 6a08568b1cb8ada309a7876907b72bd63da7f5bb..b6e209202df38baf88b30e321a1aa8d5e6936377 100644 (file)
@@ -42,13 +42,13 @@ public class PageNumberCitationLast extends AbstractPageNumberCitation {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startPageNumberCitationLast(this);
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         getFOEventHandler().endPageNumberCitationLast(this);
     }
index b001a41ee43dcbefe48842f620499a32f82c60bc..2f2b7e5a404079cbfee18e7db088eac5731f0f2e 100644 (file)
@@ -71,6 +71,18 @@ public class RetrieveMarker extends AbstractRetrieveMarker {
         setBoundaryLabel((String) pList.get(PR_RETRIEVE_BOUNDARY).getObject());
     }
 
+    @Override
+    public void startOfNode() throws FOPException {
+        super.startOfNode();
+        getFOEventHandler().startRetrieveMarker(this);
+    }
+
+    @Override
+    public void endOfNode() throws FOPException {
+        super.endOfNode();
+        getFOEventHandler().endRetrieveMarker(this);
+    }
+
     /**
      * Return the value for the <code>retrieve-position</code>
      * property
@@ -108,4 +120,10 @@ public class RetrieveMarker extends AbstractRetrieveMarker {
     public int getNameId() {
         return FO_RETRIEVE_MARKER;
     }
+
+    @Override
+    protected void restoreFOEventHandlerState() {
+        getFOEventHandler().restoreState(this);
+    }
+
 }
index efacba8640e84cbcf4aef72c6722a3d78e9e4ef7..d4bc7c687e195a17025d7d9da1da645eb3371f8e 100644 (file)
@@ -68,6 +68,18 @@ public class RetrieveTableMarker extends AbstractRetrieveMarker {
         setBoundaryLabel((String) pList.get(PR_RETRIEVE_BOUNDARY_WITHIN_TABLE).getObject());
     }
 
+    @Override
+    public void startOfNode() throws FOPException {
+        super.startOfNode();
+        getFOEventHandler().startRetrieveTableMarker(this);
+    }
+
+    @Override
+    public void endOfNode() throws FOPException {
+        super.endOfNode();
+        getFOEventHandler().endRetrieveTableMarker(this);
+    }
+
     /**
      * Return the value for the <code>retrieve-position-within-table</code>
      * property
@@ -113,4 +125,9 @@ public class RetrieveTableMarker extends AbstractRetrieveMarker {
         this.lastFOTextProcessed = null;
     }
 
+    @Override
+    protected void restoreFOEventHandlerState() {
+        getFOEventHandler().restoreState(this);
+    }
+
 }
index 0aec7ce162926300e1998a6dc9fac331784a10e9..dd15187f282f54495dff1b8ac334f619f501d009 100644 (file)
@@ -61,13 +61,13 @@ public class Wrapper extends FObjMixed implements CommonAccessibilityHolder {
     }
 
     @Override
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startWrapper(this);
     }
 
     @Override
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         getFOEventHandler().endWrapper(this);
     }
index a574723b17feb59fd31fd6c4494376356e301de7..f23ac1cc436ac16963148d1f28ee1781fcbc1885 100644 (file)
@@ -179,7 +179,7 @@ public class Table extends TableFObj implements ColumnNumberManagerHolder, Break
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startTable(this);
     }
@@ -238,7 +238,7 @@ public class Table extends TableFObj implements ColumnNumberManagerHolder, Break
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         getFOEventHandler().endTable(this);
     }
index 51db27e4ebfde8425aca5eb993a6eb06afceef49..667138e0065d847a1297e734204ba8752260f334 100644 (file)
@@ -87,7 +87,7 @@ public class TableAndCaption extends FObj implements CommonAccessibilityHolder {
      * FOEventHandler that we are at the end of the flow.
      * {@inheritDoc}
      */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (!tableFound) {
             missingChildElementError("marker* table-caption? table");
         }
index d69081e4874f63550cb82c49ab23ecffd794f332..63e9279520271fc40acfabc3ffa6d290b8e3cd00 100644 (file)
@@ -38,13 +38,13 @@ public class TableBody extends TablePart {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startBody(this);
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         getFOEventHandler().endBody(this);
     }
index 380b27f34f0e0301cb794d1deba83404207e57af..def1c109329aaba9cb35396ca13f3ec686b9e51a 100644 (file)
@@ -78,7 +78,7 @@ public class TableCaption extends FObj implements CommonAccessibilityHolder {
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (firstChild == null) {
             missingChildElementError("marker* (%block;)");
         }
index f198f3aadf52b5c303c368ef9085b8bace4b1166..20a80d13554d31e5a370e2443648191a2fbd72ad 100644 (file)
@@ -96,7 +96,7 @@ public class TableCell extends TableFObj implements CommonAccessibilityHolder {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startCell(this);
     }
@@ -106,7 +106,7 @@ public class TableCell extends TableFObj implements CommonAccessibilityHolder {
      * FOEventHandler that we are at the end of the table-cell.
      * {@inheritDoc}
      */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         getFOEventHandler().endCell(this);
     }
index cfd0136dced19a0d71d1c393022593229c75b64f..e12b75c5c94e094538a613dfe978ac4f7fab61db 100644 (file)
@@ -41,13 +41,13 @@ public class TableFooter extends TablePart {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startFooter(this);
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         getFOEventHandler().endFooter(this);
     }
index a0ad40798f64e953be49b951403ac117a1718534..73b43f30199560281d31c61763d93a190c1ebb6e 100644 (file)
@@ -40,13 +40,13 @@ public class TableHeader extends TablePart {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startHeader(this);
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         getFOEventHandler().endHeader(this);
     }
index dd9f7c6d48ca7d4dd147cc6ff1544b9cd4900cb2..2beaf2f991fc5685b8467bcdf16757382f69311b 100644 (file)
@@ -98,13 +98,13 @@ public class TableRow extends TableCellContainer implements BreakPropertySet {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startRow(this);
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         getFOEventHandler().endRow(this);
     }
index d1ccf7273055139a88ec5b9f6c1156e7cccad8e4..c74be7d7e30097cdd6652a3cf0b0fce327dcb775 100644 (file)
@@ -82,7 +82,7 @@ public abstract class AbstractPageSequence extends FObj implements CommonAccessi
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         this.pageNumberGenerator = new PageNumberGenerator(
                 format, groupingSeparator, groupingSize, letterValue,
                 numberConversionFeatures, language, country);
index da92c7439f6fda9f023d87c467d0c04bb67fe6b1..b83a72a114c778b6be4d8b805a268f0df260b207 100644 (file)
@@ -72,7 +72,7 @@ public class ConditionalPageMasterReference extends FObj {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         getConcreteParent().addConditionalPageMasterReference(this);
     }
 
index 9c68043ff61b9a727e72bd7f82ee5ec5995729d0..12d95c13173fc30754eaf500d2f9c99b2faa400b 100644 (file)
@@ -75,7 +75,7 @@ public class Declarations extends FObj {
      * a hashmap of color profiles and a list of extension attachments.
      * @throws FOPException if there's a problem during processing
      */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (firstChild != null) {
             for (FONodeIterator iter = getChildNodes(); iter.hasNext();) {
                 FONode node = iter.nextNode();
index 45c8f78041ac68f4037ac15eb3335f2142c6460d..8a52b9a9e43e5f10a7cb910b54d5bec74e109994 100644 (file)
@@ -62,7 +62,7 @@ public class Flow extends FObj implements CommonAccessibilityHolder {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         if (flowName == null || flowName.equals("")) {
             missingPropertyError(FLOW_NAME);
         }
@@ -88,7 +88,7 @@ public class Flow extends FObj implements CommonAccessibilityHolder {
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (!blockItemFound) {
             missingChildElementError("marker* (%block;)+");
         }
index 8b109dd0e0e8de77d877f6fea6bd7eab932f2378..905291b35ecf3aa41560039fc796bee62519db18 100644 (file)
@@ -62,14 +62,14 @@ public class LayoutMasterSet extends FObj {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         getRoot().setLayoutMasterSet(this);
         simplePageMasters = new java.util.HashMap<String, SimplePageMaster>();
         pageSequenceMasters = new java.util.HashMap<String, PageSequenceMaster>();
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (firstChild == null) {
             missingChildElementError("(simple-page-master|page-sequence-master)+");
         }
index 6039dafebf1b45b96d03b2b1aaf9a7b6e6a2ff5c..6b1ee2ef416cf8f4a176fa86e2d9b282b9659bf4 100644 (file)
@@ -103,7 +103,7 @@ public class PageSequence extends AbstractPageSequence implements WritingModeTra
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         flowMap = new java.util.HashMap<String, FONode>();
 
@@ -121,7 +121,7 @@ public class PageSequence extends AbstractPageSequence implements WritingModeTra
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (mainFlow == null) {
            missingChildElementError("(title?,static-content*,flow)");
         }
index 080d663d71a67536449be5eaedd8ea78d348edf0..6fa9b4261fc9e59ecbd8e9f3864134a5cdeea813 100644 (file)
@@ -79,14 +79,14 @@ public class PageSequenceMaster extends FObj {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         subSequenceSpecifiers = new java.util.ArrayList<SubSequenceSpecifier>();
         layoutMasterSet = parent.getRoot().getLayoutMasterSet();
         layoutMasterSet.addPageSequenceMaster(masterName, this);
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (firstChild == null) {
             missingChildElementError("(single-page-master-reference|"
                     + "repeatable-page-master-reference|repeatable-page-master-alternatives)+");
index 8ade4d34a73c5938d72f5332d639f734b6db129b..439ed28598a2cef52c325efdffc52a1dd2444018 100644 (file)
@@ -68,7 +68,7 @@ public class RepeatablePageMasterAlternatives extends FObj
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         conditionalPageMasterRefs = new java.util.ArrayList<ConditionalPageMasterReference>();
 
         assert parent.getName().equals("fo:page-sequence-master"); //Validation by the parent
@@ -77,7 +77,7 @@ public class RepeatablePageMasterAlternatives extends FObj
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (firstChild == null) {
            missingChildElementError("(conditional-page-master-reference+)");
         }
index c3f2368ea193945a1b516916625914c0aeaf5cf5..9ea1ab50afcbdc1cd94fa8da0431222bd9f47f5c 100644 (file)
@@ -70,7 +70,7 @@ public class RepeatablePageMasterReference extends FObj
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         PageSequenceMaster pageSequenceMaster = (PageSequenceMaster) parent;
 
         if (masterReference == null) {
index 6db8d6db1167eb91641ee5482a21872802f10d7a..64a6b039d38764dd80e9f11bd336c8c477dc9ebf 100644 (file)
@@ -97,12 +97,12 @@ public class Root extends FObj implements CommonAccessibilityHolder {
     }
 
      /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         foEventHandler.startRoot(this);
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (!pageSequenceFound || layoutMasterSet == null) {
             missingChildElementError("(layout-master-set, declarations?, "
                 + "bookmark-tree?, (page-sequence|fox:external-document)+)");
index 79c8c3358afc66d439cb7f54e5e7b44a49e154e7..637289cdee05cec5949898cc3cd621bfd47c518c 100644 (file)
@@ -89,7 +89,7 @@ public class SimplePageMaster extends FObj {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         LayoutMasterSet layoutMasterSet = (LayoutMasterSet) parent;
 
         if (masterName == null) {
@@ -103,7 +103,7 @@ public class SimplePageMaster extends FObj {
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (!hasRegionBody) {
             missingChildElementError(
                     "(region-body, region-before?, region-after?, region-start?, region-end?)");
index 38b56af198da29b3502dd4c4c5d49b5bac43d049..ed0c041ddb165478abb07cbff924f6ebad634f2a 100644 (file)
@@ -71,7 +71,7 @@ public class SinglePageMasterReference extends FObj
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         PageSequenceMaster pageSequenceMaster = (PageSequenceMaster) parent;
         pageSequenceMaster.addSubsequenceSpecifier(this);
     }
index 412cdbcca97bf13845b64671c6f37ce39ba00d23..d85ab5f3000e388e6ed4d69c5e26c230c04fff9f 100644 (file)
@@ -40,7 +40,7 @@ public class StaticContent extends Flow {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         if (getFlowName() == null || getFlowName().equals("")) {
             missingPropertyError(FLOW_NAME);
         }
@@ -52,7 +52,7 @@ public class StaticContent extends Flow {
      * FOEventHandler that we are at the end of the flow.
      * {@inheritDoc}
      */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (firstChild == null && getUserAgent().validateStrictly()) {
             missingChildElementError("(%block;)+");
         }
index 9e7d80ceaf75f997c4582b911c3f0fb079f51c4c..9cefe85b4f0d330fd00eb9c32c9220ada911da04 100644 (file)
@@ -102,7 +102,7 @@ public class Bookmark extends FObj implements CommonAccessibilityHolder {
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (bookmarkTitle == null) {
            missingChildElementError("(bookmark-title, bookmark*)");
         }
index 22bf0769b46e1fddb9b6d82af9d037aec10ebcc5..c5594bff090fa5b007ed80906ab566d9e7f0ca44 100644 (file)
@@ -56,7 +56,7 @@ public class BookmarkTree extends FObj {
     }
 
     /** {@inheritDoc} */
-        protected void endOfNode() throws FOPException {
+        public void endOfNode() throws FOPException {
         if (bookmarks == null) {
            missingChildElementError("(fo:bookmark+)");
         }
index 8250318d769703624c967d4e6664a6cf3fd0bff7..badf53060c8b7a7c55ef1b296c5041880a697645 100644 (file)
@@ -37,7 +37,7 @@ public class PDFStructElem extends StructureHierarchyMember
 
     private StructureType structureType;
 
-    private PDFStructElem parentElement;
+    protected PDFStructElem parentElement;
 
     /**
      * Elements to be added to the kids array.
@@ -231,6 +231,9 @@ public class PDFStructElem extends StructureHierarchyMember
                         textBuffer.append(' ');
                     }
                     Object obj = kids.get(i);
+                    if (obj instanceof PDFStructElem) {
+                        ((PDFStructElem) obj).setParent(parentElement);
+                    }
                     formatObject(obj, out, textBuffer);
                 }
             }
index c5079b2bd9c807af3ca007414d67d0d275cffe1b..71765bb7d3fe9e24108cc185b3a10ed194dd73af 100644 (file)
@@ -54,7 +54,7 @@ public class AFPIncludeFormMapElement extends AbstractAFPExtensionObject {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         if (parent.getNameId() != Constants.FO_DECLARATIONS) {
             invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(),
index 813cf6ddd642da40603a4a326d1e057c132ec679..e40d3da34dca41fa5bafb7842bd1d1d41bf3af0b 100644 (file)
@@ -40,7 +40,7 @@ public class AFPInvokeMediumMapElement extends AbstractAFPExtensionObject {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         if (parent.getNameId() != Constants.FO_PAGE_SEQUENCE
                 && parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER) {
index 0b9645236cdc0cea4cde96ede5a1483b65d8bab4..59df1529e0982177641efbba6cf582e5bdea1dc2 100644 (file)
@@ -57,7 +57,7 @@ public class AFPPageOverlayElement extends AbstractAFPExtensionObject {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         if (AFPElementMapping.INCLUDE_PAGE_OVERLAY.equals(getLocalName())) {
             if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER
index 9b325c5cd80a1b4124bad4af9dc66499318d110e..e3aa3ca57f25634bdbb36e04140b1201806d7666 100644 (file)
@@ -54,7 +54,7 @@ public class AFPPageSetupElement extends AbstractAFPExtensionObject {
 
     /** {@inheritDoc} */
     @Override
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         if (AFPElementMapping.TAG_LOGICAL_ELEMENT.equals(getLocalName())) {
             if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER
index e35a13ec6bbfccb55becd16bd2a32f6fcb2ce068..388ea3f4469971d6b046852b4967425ad39b1b67 100644 (file)
@@ -86,7 +86,7 @@ public abstract class AbstractAFPExtensionObject extends FONode {
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
     }
 
index 5753dad014d7b1d2ab55075e438c1e8858ca94e8..484e8d559d9d105375be77f75e1ddc7a62f2522d 100644 (file)
@@ -163,25 +163,15 @@ public class IFParser implements IFConstants {
         private Map<String, StructureTreeElement> structureTreeElements
                 = new HashMap<String, StructureTreeElement>();
 
-        private final class StructureTreeHandler extends DefaultHandler {
+        private class StructureTreeHandler extends DefaultHandler {
 
-            private final Locale pageSequenceLanguage;
-
-            private final StructureTreeEventHandler structureTreeEventHandler;
+            protected final StructureTreeEventHandler structureTreeEventHandler;
 
-            private StructureTreeHandler(StructureTreeEventHandler structureTreeEventHandler,
-                    Locale pageSequenceLanguage) throws SAXException {
-                this.pageSequenceLanguage = pageSequenceLanguage;
+            StructureTreeHandler(StructureTreeEventHandler structureTreeEventHandler) {
                 this.structureTreeEventHandler = structureTreeEventHandler;
             }
 
             void startStructureTree(String type) {
-                structureTreeEventHandler.startPageSequence(pageSequenceLanguage, type);
-            }
-
-            public void endDocument() throws SAXException {
-                startIFElement(EL_PAGE_SEQUENCE, pageSequenceAttributes);
-                pageSequenceAttributes = null;
             }
 
             @Override
@@ -191,18 +181,19 @@ public class IFParser implements IFConstants {
                     if (localName.equals("marked-content")) {
                         localName = "#PCDATA";
                     }
+                    StructureTreeElement parent = getStructureTreeElement(attributes);
                     String structID = attributes.getValue(InternalElementMapping.URI,
                             InternalElementMapping.STRUCT_ID);
                     if (structID == null) {
-                        structureTreeEventHandler.startNode(localName, attributes);
+                        structureTreeEventHandler.startNode(localName, attributes, parent);
                     } else if (localName.equals("external-graphic")
                             || localName.equals("instream-foreign-object")) {
                         StructureTreeElement structureTreeElement
-                                = structureTreeEventHandler.startImageNode(localName, attributes);
+                                = structureTreeEventHandler.startImageNode(localName, attributes, parent);
                         structureTreeElements.put(structID, structureTreeElement);
                     } else {
                         StructureTreeElement structureTreeElement = structureTreeEventHandler
-                                    .startReferencedNode(localName, attributes);
+                                    .startReferencedNode(localName, attributes, parent);
                         structureTreeElements.put(structID, structureTreeElement);
                     }
                 }
@@ -217,6 +208,28 @@ public class IFParser implements IFConstants {
             }
         }
 
+        private class MainStructureTreeHandler extends StructureTreeHandler {
+
+            private final Locale pageSequenceLanguage;
+
+            MainStructureTreeHandler(StructureTreeEventHandler structureTreeEventHandler,
+                    Locale pageSequenceLanguage) throws SAXException {
+                super(structureTreeEventHandler);
+                this.pageSequenceLanguage = pageSequenceLanguage;
+            }
+
+            @Override
+            void startStructureTree(String type) {
+                structureTreeEventHandler.startPageSequence(pageSequenceLanguage, type);
+            }
+
+            public void endDocument() throws SAXException {
+                startIFElement(EL_PAGE_SEQUENCE, pageSequenceAttributes);
+                pageSequenceAttributes = null;
+            }
+
+        }
+
         public Handler(IFDocumentHandler documentHandler, FOUserAgent userAgent,
                 ElementMappingRegistry elementMappingRegistry) {
             this.documentHandler = documentHandler;
@@ -264,7 +277,7 @@ public class IFParser implements IFConstants {
                     if (localName.equals(EL_PAGE_SEQUENCE) && userAgent.isAccessibilityEnabled()) {
                         pageSequenceAttributes = new AttributesImpl(attributes);
                         Locale language = getLanguage(attributes);
-                        structureTreeHandler = new StructureTreeHandler(
+                        structureTreeHandler = new MainStructureTreeHandler(
                                 userAgent.getStructureTreeEventHandler(), language);
 
                     } else if (localName.equals(EL_STRUCTURE_TREE)) {
@@ -520,6 +533,7 @@ public class IFParser implements IFConstants {
 
             public void startElement(Attributes attributes) throws IFException {
                 documentHandler.startPageHeader();
+                structureTreeHandler = new StructureTreeHandler(userAgent.getStructureTreeEventHandler());
             }
 
             public void endElement() throws IFException {
@@ -842,12 +856,19 @@ public class IFParser implements IFConstants {
         }
 
         private void establishStructureTreeElement(Attributes attributes) {
-            String structRef = attributes.getValue(InternalElementMapping.URI,
-                    InternalElementMapping.STRUCT_REF);
+            StructureTreeElement element = getStructureTreeElement(attributes);
+            if (element != null) {
+                documentHandler.getContext().setStructureTreeElement(element);
+            }
+        }
+
+        private StructureTreeElement getStructureTreeElement(Attributes attributes) {
+            String structRef = attributes.getValue(InternalElementMapping.URI, InternalElementMapping.STRUCT_REF);
             if (structRef != null && structRef.length() > 0) {
                 assert structureTreeElements.containsKey(structRef);
-                StructureTreeElement structureTreeElement = structureTreeElements.get(structRef);
-                documentHandler.getContext().setStructureTreeElement(structureTreeElement);
+                return structureTreeElements.get(structRef);
+            } else {
+                return null;
             }
         }
 
index ff3f761bf373b1f9e84181cdd149eddd66729b37..bba8c744dc0e1924c47ea970f6ca7b90b5d76503 100644 (file)
@@ -314,6 +314,9 @@ implements IFConstants, IFPainter, IFDocumentNavigationHandler {
     public void startPageHeader() throws IFException {
         try {
             handler.startElement(EL_PAGE_HEADER);
+            if (this.getUserAgent().isAccessibilityEnabled()) {
+                structureTreeBuilder.replayEventsForRetrievedMarkers(handler);
+            }
         } catch (SAXException e) {
             throw new IFException("SAX error in startPageHeader()", e);
         }
index 9ba9afd81b22bdea97840f063151754d6bb6c30a..f7049997e579859b00d1177cedab29e864ca9df2 100644 (file)
@@ -33,6 +33,7 @@ import org.apache.fop.accessibility.StructureTree2SAXEventAdapter;
 import org.apache.fop.accessibility.StructureTreeElement;
 import org.apache.fop.accessibility.StructureTreeEventHandler;
 import org.apache.fop.fo.extensions.InternalElementMapping;
+import org.apache.fop.util.XMLConstants;
 import org.apache.fop.util.XMLUtil;
 
 /**
@@ -176,6 +177,8 @@ final class IFStructureTreeBuilder implements StructureTreeEventHandler {
     private final List<SAXEventRecorder> pageSequenceEventRecorders
             = new ArrayList<SAXEventRecorder>();
 
+    private SAXEventRecorder retrievedMarkersEventRecorder;
+
     private int idCounter;
 
     /**
@@ -189,6 +192,16 @@ final class IFStructureTreeBuilder implements StructureTreeEventHandler {
         pageSequenceEventRecorders.get(pageSequenceIndex).replay(handler);
     }
 
+    public void replayEventsForRetrievedMarkers(ContentHandler handler) throws SAXException {
+        if (!retrievedMarkersEventRecorder.events.isEmpty()) {
+            delegate = StructureTree2SAXEventAdapter.newInstance(handler);
+            delegate.startPageSequence(null, null);
+            retrievedMarkersEventRecorder.replay(handler);
+            delegate.endPageSequence();
+            prepareRetrievedMarkersEventRecorder();
+        }
+    }
+
     public void startPageSequence(Locale locale, String role) {
         SAXEventRecorder eventRecorder = new SAXEventRecorder();
         pageSequenceEventRecorders.add(eventRecorder);
@@ -198,28 +211,51 @@ final class IFStructureTreeBuilder implements StructureTreeEventHandler {
 
     public void endPageSequence() {
          delegate.endPageSequence();
+         prepareRetrievedMarkersEventRecorder();
+    }
+
+    private void prepareRetrievedMarkersEventRecorder() {
+        SAXEventRecorder eventRecorder = new SAXEventRecorder();
+        retrievedMarkersEventRecorder = eventRecorder;
+        delegate = StructureTree2SAXEventAdapter.newInstance(eventRecorder);
     }
 
-    public StructureTreeElement startNode(String name, Attributes attributes) {
-        delegate.startNode(name, attributes);
+    public StructureTreeElement startNode(String name, Attributes attributes, StructureTreeElement parent) {
+        if (parent != null) {
+            attributes = addParentAttribute(new AttributesImpl(attributes), parent);
+        }
+        delegate.startNode(name, attributes, null);
         return new IFStructureTreeElement();
     }
 
+    private AttributesImpl addParentAttribute(AttributesImpl attributes, StructureTreeElement parent) {
+        if (parent != null) {
+            attributes.addAttribute(InternalElementMapping.URI,
+                    InternalElementMapping.STRUCT_REF,
+                    InternalElementMapping.STANDARD_PREFIX + ":" + InternalElementMapping.STRUCT_REF,
+                    XMLConstants.CDATA,
+                    ((IFStructureTreeElement) parent).getId());
+        }
+        return attributes;
+    }
+
     public void endNode(String name) {
         delegate.endNode(name);
     }
 
-    public StructureTreeElement startImageNode(String name, Attributes attributes) {
+    public StructureTreeElement startImageNode(String name, Attributes attributes, StructureTreeElement parent) {
         String id = getNextID();
         AttributesImpl atts = addIDAttribute(attributes, id);
-        delegate.startImageNode(name, atts);
+        addParentAttribute(atts, parent);
+        delegate.startImageNode(name, atts, null);
         return new IFStructureTreeElement(id);
     }
 
-    public StructureTreeElement startReferencedNode(String name, Attributes attributes) {
+    public StructureTreeElement startReferencedNode(String name, Attributes attributes, StructureTreeElement parent) {
         String id = getNextID();
         AttributesImpl atts = addIDAttribute(attributes, id);
-        delegate.startReferencedNode(name, atts);
+        addParentAttribute(atts, parent);
+        delegate.startReferencedNode(name, atts, null);
         return new IFStructureTreeElement(id);
     }
 
index c532a05a4f4e95a43a144b20c39770db88e126f6..2eb5bc8aa1c1dc8b93e65707ce43bcf81dd2a342 100644 (file)
@@ -128,9 +128,10 @@ class PDFLogicalStructureHandler {
     }
 
     private MarkedContentInfo addToParentTree(PDFStructElem structureTreeElement) {
-        PDFStructElem parent = (structureTreeElement instanceof PDFStructElem.Placeholder)
-                ? structureTreeElement.getParentStructElem()
-                : structureTreeElement;
+        PDFStructElem parent = structureTreeElement;
+        while (parent instanceof PDFStructElem.Placeholder) {
+            parent = parent.getParentStructElem();
+        }
         pageParentTreeArray.add(parent);
         String type = parent.getStructureType().getName().toString();
         int mcid = pageParentTreeArray.length() - 1;
index 08aad08f6159d4aff66dd48cd7fa97b10020cc96..4d34b8be4d726f5a85a9b42f5ff83b48a7efe9e8 100644 (file)
@@ -96,8 +96,11 @@ class PDFStructureTreeBuilder implements StructureTreeEventHandler {
         addBuilder("float",                     StandardStructureTypes.Grouping.DIV);
         addBuilder("footnote",                  StandardStructureTypes.InlineLevelStructure.NOTE);
         addBuilder("footnote-body",             StandardStructureTypes.Grouping.SECT);
+        // Other Formatting Objects
         addBuilder("wrapper",                   StandardStructureTypes.InlineLevelStructure.SPAN);
         addBuilder("marker",                    StandardStructureTypes.Grouping.PRIVATE);
+        addBuilder("retrieve-marker",           new PlaceholderBuilder());
+        addBuilder("retrieve-table-marker",     new PlaceholderBuilder());
 
         addBuilder("#PCDATA", new PlaceholderBuilder());
     }
@@ -354,9 +357,9 @@ class PDFStructureTreeBuilder implements StructureTreeEventHandler {
     public void endPageSequence() {
     }
 
-    public StructureTreeElement startNode(String name, Attributes attributes) {
-        PDFStructElem parent = ancestors.getFirst();
-        PDFStructElem structElem = createStructureElement(name, parent, attributes,
+    public StructureTreeElement startNode(String name, Attributes attributes, StructureTreeElement parent) {
+        PDFStructElem parentElem = parent == null ? ancestors.getFirst() : (PDFStructElem) parent;
+        PDFStructElem structElem = createStructureElement(name, parentElem, attributes,
                 pdfFactory, eventBroadcaster);
         ancestors.addFirst(structElem);
         return structElem;
@@ -366,12 +369,12 @@ class PDFStructureTreeBuilder implements StructureTreeEventHandler {
         ancestors.removeFirst();
     }
 
-    public StructureTreeElement startImageNode(String name, Attributes attributes) {
-        return startNode(name, attributes);
+    public StructureTreeElement startImageNode(String name, Attributes attributes, StructureTreeElement parent) {
+        return startNode(name, attributes, parent);
     }
 
-    public StructureTreeElement startReferencedNode(String name, Attributes attributes) {
-        return startNode(name, attributes);
+    public StructureTreeElement startReferencedNode(String name, Attributes attributes, StructureTreeElement parent) {
+        return startNode(name, attributes, parent);
     }
 
 }
index b2d85dd1016938365f9e262521d56be10cd96d53..36d7c18d26123ec8865b3101a80c2ff16b5ed9b7 100644 (file)
@@ -49,7 +49,7 @@ public class PDFEmbeddedFileElement extends AbstractPDFExtensionElement {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         if (parent.getNameId() != Constants.FO_DECLARATIONS) {
             invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(),
index a8bab26b640148d4546618064e3991d7fa0571e7..11b2e5f7b355e0ac05269f045513909383c47714 100644 (file)
@@ -42,7 +42,7 @@ public abstract class AbstractPSCommentElement extends AbstractPSExtensionElemen
      * @throws FOPException if there's a problem during processing
      * @see org.apache.fop.fo.FONode#startOfNode()
      */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         if (parent.getNameId() != Constants.FO_DECLARATIONS
                 && parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER) {
             invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(),
index 3f534af7eee22bfa10a25c64c30fcebdee32ffa5..c79d316138c96a7a0099cb99eabb74c26960fc12 100644 (file)
@@ -97,7 +97,7 @@ public abstract class AbstractPSExtensionElement extends FONode {
      * @see org.apache.fop.fo.FONode#endOfNode()
      * @throws FOPException if there's a problem during processing
      */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         String s = ((PSExtensionAttachment)getExtensionAttachment()).getContent();
         if (s == null || s.length() == 0) {
index d097e7b5edf86926eaabc754b66e0323bf0d9858..1ee48d9d6ddbc8633c60c5ea879d0d2c666d662a 100644 (file)
@@ -86,7 +86,7 @@ public abstract class AbstractPSExtensionObject extends FONode {
     }
 
     /** {@inheritDoc} */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         super.endOfNode();
         String s = setupCode.getContent();
         if (s == null || s.length() == 0) {
index 686667c3d60ea30ac63bcfe466bac50958bc7659..cf2ea9444c9049de9e96cf86a0c999d576d42ab6 100644 (file)
@@ -40,7 +40,7 @@ public class PSPageSetupCodeElement extends AbstractPSExtensionObject {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER) {
             invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(),
index 6cdd1c60c5b8d60fdc15522a0ad95459d0f24ef7..ebae5baaf78b0600744344d1cc8cf329c04ea9a9 100644 (file)
@@ -49,7 +49,7 @@ public class PSSetPageDeviceElement extends AbstractPSExtensionElement {
      * @throws FOPException if there's a problem during processing
      * @see org.apache.fop.fo.FONode#startOfNode()
      */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         if ( !((parent.getNameId() == Constants.FO_DECLARATIONS)
                 || (parent.getNameId() == Constants.FO_SIMPLE_PAGE_MASTER)) ) {
index 4ac0af2b79301c998bb8a81553a7d4fbacc23336..3652754551f5fc7a4d0572c40f9e2e81bbc77a5c 100644 (file)
@@ -40,7 +40,7 @@ public class PSSetupCodeElement extends AbstractPSExtensionObject {
     }
 
     /** {@inheritDoc} */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         if (parent.getNameId() != Constants.FO_DECLARATIONS) {
             invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(),
index 6819fed794daf5596f34a09489e7db1f8295f0f8..4df3fe278d00adbfade90e34f395f3625856e97f 100644 (file)
@@ -90,7 +90,7 @@ public class IFStructureTreeBuilderTestCase {
         final ContentHandler handler = mock(ContentHandler.class);
 
         sut.startPageSequence(null, null);
-        sut.startNode(nodeName, createSimpleAttributes(attributes));
+        sut.startNode(nodeName, createSimpleAttributes(attributes), null);
         sut.endPageSequence();
 
         sut.replayEventsForPageSequence(handler, 0);
diff --git a/test/pdf/accessibility/markers.fo b/test/pdf/accessibility/markers.fo
new file mode 100644 (file)
index 0000000..67dbfc3
--- /dev/null
@@ -0,0 +1,169 @@
+<?xml version="1.0" standalone="no"?>
+<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
+  xmlns:fox="http://xmlgraphics.apache.org/fop/extensions" xml:lang="en-GB">
+  <fo:layout-master-set>
+    <fo:simple-page-master master-name="page"
+      page-height="200pt" page-width="280pt" margin="10pt">
+      <fo:region-body/>
+      <fo:region-after extent="100pt" display-align="after"/>
+    </fo:simple-page-master>
+  </fo:layout-master-set>
+  <fo:page-sequence master-reference="page">
+    <fo:static-content flow-name="xsl-region-after" line-height="10pt" font-size="8pt">
+      <fo:block>Retrieving the marker:</fo:block>
+      <fo:retrieve-marker retrieve-class-name="marker"/>
+      <fo:block>Marker retrieved.</fo:block>
+    </fo:static-content>
+    <fo:flow flow-name="xsl-region-body">
+      <fo:block><fo:marker marker-class-name="marker">
+          <fo:table width="100%" table-layout="fixed">
+            <fo:table-header>
+              <fo:table-row>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block-container>
+                    <fo:block>Inside a block-container.</fo:block>
+                  </fo:block-container>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block>A character: <fo:character character="c" color="blue"/>.</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block text-align="center"><fo:instream-foreign-object fox:alt-text="Nice 
+                      circles." width="30pt" overflow="hidden" display-align="center" 
+                      content-width="30pt">
+                      <svg xmlns="http://www.w3.org/2000/svg" width="319" height="286.6">
+                        <g style="fill-opacity:0.7; stroke:black; stroke-width:3"
+                          transform="translate(0, 286.6) scale(1, -1) translate(100, 100)">
+                          <circle cx="50"  cy="86.6" r="80" style="fill:red;"/>
+                          <circle cx="0"   cy="0"    r="80" style="fill:green;"/>
+                          <circle cx="100" cy="0"    r="80" style="fill:blue;"/>
+                        </g>
+                      </svg>
+                  </fo:instream-foreign-object></fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block text-align-last="justify">Lead<fo:leader leader-pattern="dots" 
+                      leader-length.minimum="0" leader-length.optimum="100%"/>er.</fo:block>
+                  <fo:block>Page <fo:page-number/>.</fo:block>
+                  <fo:block-container absolute-position="absolute" width="35pt" height="10pt" top="20pt" 
+                    right="2pt" color="purple" text-align="right">
+                    <fo:block>Absolute.</fo:block>
+                  </fo:block-container>
+                </fo:table-cell>
+              </fo:table-row>
+            </fo:table-header>
+            <fo:table-body>
+              <fo:table-row>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block>1.1</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block>1.2</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block>1.3</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block>1.4</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+              <fo:table-row>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block>2.1</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block>2.2</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block>2.3</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block>2.4</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+            </fo:table-body>
+      </fo:table></fo:marker>Text in the region-body.</fo:block>
+    </fo:flow>
+  </fo:page-sequence>
+
+  <fo:page-sequence master-reference="page">
+    <fo:static-content flow-name="xsl-region-after" line-height="10pt" font-size="8pt" 
+      role="artifact">
+      <fo:block>This whole page footer should neither appear in the structure tree nor be read out 
+        loud.</fo:block>
+      <fo:block>Retrieving the marker:</fo:block>
+      <fo:retrieve-marker retrieve-class-name="marker"/>
+      <fo:block>Marker retrieved.</fo:block>
+    </fo:static-content>
+    <fo:flow flow-name="xsl-region-body">
+      <fo:block><fo:marker marker-class-name="marker">
+          <fo:table width="100%" table-layout="fixed">
+            <fo:table-header>
+              <fo:table-row>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block-container>
+                    <fo:block>Inside a block-container.</fo:block>
+                  </fo:block-container>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block>A character: <fo:character character="c" color="blue"/>.</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block text-align="center"><fo:instream-foreign-object fox:alt-text="Nice 
+                      circles." width="30pt" overflow="hidden" display-align="center" 
+                      content-width="30pt">
+                      <svg xmlns="http://www.w3.org/2000/svg" width="319" height="286.6">
+                        <g style="fill-opacity:0.7; stroke:black; stroke-width:3"
+                          transform="translate(0, 286.6) scale(1, -1) translate(100, 100)">
+                          <circle cx="50"  cy="86.6" r="80" style="fill:red;"/>
+                          <circle cx="0"   cy="0"    r="80" style="fill:green;"/>
+                          <circle cx="100" cy="0"    r="80" style="fill:blue;"/>
+                        </g>
+                      </svg>
+                  </fo:instream-foreign-object></fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block text-align-last="justify">Lead<fo:leader leader-pattern="dots" 
+                      leader-length.minimum="0" leader-length.optimum="100%"/>er.</fo:block>
+                  <fo:block>Page <fo:page-number/>.</fo:block>
+                  <fo:block-container absolute-position="absolute" width="35pt" height="10pt" top="20pt" 
+                    right="2pt" color="purple" text-align="right">
+                    <fo:block>Absolute.</fo:block>
+                  </fo:block-container>
+                </fo:table-cell>
+              </fo:table-row>
+            </fo:table-header>
+            <fo:table-body>
+              <fo:table-row>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block>1.1</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block>1.2</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block>1.3</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block>1.4</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+              <fo:table-row>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block>2.1</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block>2.2</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block>2.3</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid black">
+                  <fo:block>2.4</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+            </fo:table-body>
+      </fo:table></fo:marker>Text in the region-body.</fo:block>
+    </fo:flow>
+  </fo:page-sequence>
+</fo:root>
diff --git a/test/pdf/accessibility/pdf/markers.pdf b/test/pdf/accessibility/pdf/markers.pdf
new file mode 100644 (file)
index 0000000..752fbd1
Binary files /dev/null and b/test/pdf/accessibility/pdf/markers.pdf differ