]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Implemented rendering of structure tree to Area Tree XML and parsing back from it
authorVincent Hennebert <vhennebert@apache.org>
Tue, 13 Oct 2009 16:14:12 +0000 (16:14 +0000)
committerVincent Hennebert <vhennebert@apache.org>
Tue, 13 Oct 2009 16:14:12 +0000 (16:14 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_Accessibility@824827 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/accessibility/ParsedStructureTree.java
src/java/org/apache/fop/area/AreaTreeParser.java
src/java/org/apache/fop/render/xml/XMLRenderer.java

index 69b26c21cf990afa1ca0d74bdc4bd7cc87b708c8..3aa95b62767418da9aadf6b2ded23c974dc7c3d5 100644 (file)
 
 package org.apache.fop.accessibility;
 
+import java.io.StringWriter;
+import java.io.Writer;
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 
+import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.sax.SAXTransformerFactory;
 import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
 
 import org.w3c.dom.NodeList;
 import org.xml.sax.ContentHandler;
@@ -92,4 +99,28 @@ public class ParsedStructureTree implements StructureTree {
         return (NodeList) pageSequenceStructures.get(number - 1);
     }
 
+    /**
+     * Returns an XML-like representation of the structure trees.
+     * <p>
+     * <strong>Note:</strong> use only for debugging purpose, as this method
+     * performs non-trivial operations.
+     * </p>
+     * @return a string representation of this object
+     */
+    public String toString() {
+        try {
+            Transformer t = TransformerFactory.newInstance().newTransformer();
+            Writer str = new StringWriter();
+            for (Iterator iter = pageSequenceStructures.iterator(); iter.hasNext();) {
+                NodeList nodes = (NodeList) iter.next();
+                for (int i = 0, c = nodes.getLength(); i < c; i++) {
+                    t.transform(new DOMSource(nodes.item(i)), new StreamResult(str));
+                }
+            }
+            return str.toString();
+        } catch (Exception e) {
+            return e.toString();
+        }
+    }
+
 }
index 25d1100866f006f5b76fb661c7932a11e012a111..12e31530d4ce52727a015ae7b5057008122b262a 100644 (file)
@@ -39,8 +39,6 @@ import javax.xml.transform.sax.SAXResult;
 import javax.xml.transform.sax.SAXTransformerFactory;
 import javax.xml.transform.sax.TransformerHandler;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.w3c.dom.DOMImplementation;
 import org.w3c.dom.Document;
 import org.xml.sax.Attributes;
@@ -50,12 +48,16 @@ import org.xml.sax.SAXException;
 import org.xml.sax.helpers.AttributesImpl;
 import org.xml.sax.helpers.DefaultHandler;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
 import org.apache.xmlgraphics.image.loader.ImageException;
 import org.apache.xmlgraphics.image.loader.ImageInfo;
 import org.apache.xmlgraphics.image.loader.ImageManager;
 import org.apache.xmlgraphics.image.loader.ImageSessionContext;
 import org.apache.xmlgraphics.util.QName;
 
+import org.apache.fop.accessibility.ParsedStructureTree;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.area.Trait.Background;
 import org.apache.fop.area.Trait.InternalLink;
@@ -84,6 +86,7 @@ import org.apache.fop.util.ContentHandlerFactory;
 import org.apache.fop.util.ContentHandlerFactoryRegistry;
 import org.apache.fop.util.ConversionUtils;
 import org.apache.fop.util.DefaultErrorListener;
+import org.apache.fop.util.DelegatingContentHandler;
 import org.apache.fop.util.XMLConstants;
 import org.apache.fop.util.XMLUtil;
 
@@ -157,6 +160,26 @@ public class AreaTreeParser {
         private Locator locator;
 
 
+        private ParsedStructureTree structureTree;
+
+        private ContentHandler structureTreeBuilder;
+
+        private final class StructureTreeBuilder extends DelegatingContentHandler {
+
+            private Attributes pageSequenceAttributes;
+
+            private StructureTreeBuilder(Attributes pageSequenceAttributes,
+                    ParsedStructureTree structureTree) throws SAXException {
+                super(structureTree.getHandlerForNextPageSequence());
+                this.pageSequenceAttributes = new AttributesImpl(pageSequenceAttributes);
+            }
+
+            public void endDocument() throws SAXException {
+                super.endDocument();
+                startAreaTreeElement("pageSequence", pageSequenceAttributes);
+            }
+        }
+
         public Handler(AreaTreeModel treeModel, FOUserAgent userAgent,
                 ElementMappingRegistry elementMappingRegistry) {
             this.treeModel = treeModel;
@@ -193,6 +216,10 @@ public class AreaTreeParser {
             makers.put("bookmarkTree", new BookmarkTreeMaker());
             makers.put("bookmark", new BookmarkMaker());
             makers.put("destination", new DestinationMaker());
+            if (userAgent.isAccessibilityEnabled()) {
+                structureTree = new ParsedStructureTree(tFactory);
+                userAgent.setStructureTree(structureTree);
+            }
         }
 
         private Area findAreaType(Class clazz) {
@@ -266,19 +293,22 @@ public class AreaTreeParser {
                 delegate.startDocument();
                 delegate.startElement(uri, localName, qName, attributes);
             } else {
-                lastAttributes = new AttributesImpl(attributes);
                 boolean handled = true;
                 if ("".equals(uri)) {
-                    Maker maker = (Maker)makers.get(localName);
-                    content.clear();
-                    ignoreCharacters = true;
-                    if (maker != null) {
-                        ignoreCharacters = maker.ignoreCharacters();
-                        maker.startElement(attributes);
-                    } else if ("extension-attachments".equals(localName)) {
-                        //TODO implement me
+                    if (localName.equals("pageSequence") && userAgent.isAccessibilityEnabled()) {
+                        structureTreeBuilder = new StructureTreeBuilder(attributes, structureTree);
+                    } else if (localName.equals("structureTree")) {
+                        if (userAgent.isAccessibilityEnabled()) {
+                            delegate = structureTreeBuilder;
+                        } else {
+                            /* Delegate to a handler that does nothing */
+                            delegate = new DefaultHandler();
+                        }
+                        delegateStack.push(qName);
+                        delegate.startDocument();
+                        delegate.startElement(uri, localName, qName, attributes);
                     } else {
-                        handled = false;
+                        handled = startAreaTreeElement(localName, attributes);
                     }
                 } else {
                     ContentHandlerFactoryRegistry registry
@@ -305,6 +335,23 @@ public class AreaTreeParser {
             }
         }
 
+        private boolean startAreaTreeElement(String localName, Attributes attributes)
+                throws SAXException {
+            lastAttributes = new AttributesImpl(attributes);
+            Maker maker = (Maker)makers.get(localName);
+            content.clear();
+            ignoreCharacters = true;
+            if (maker != null) {
+                ignoreCharacters = maker.ignoreCharacters();
+                maker.startElement(attributes);
+            } else if ("extension-attachments".equals(localName)) {
+                //TODO implement me
+            } else {
+                return false;
+            }
+            return true;
+        }
+
         /** {@inheritDoc} */
         public void endElement(String uri, String localName, String qName) throws SAXException {
             if (delegate != null) {
@@ -701,6 +748,7 @@ public class AreaTreeParser {
                 setTraits(attributes, ip, SUBSET_BOX);
                 setTraits(attributes, ip, SUBSET_COLOR);
                 setTraits(attributes, ip, SUBSET_LINK);
+                setPtr(ip, attributes);
                 Area parent = (Area)areaStack.peek();
                 parent.addChildArea(ip);
                 areaStack.push(ip);
@@ -749,6 +797,7 @@ public class AreaTreeParser {
                         "tlsadjust", 0));
                 text.setTextWordSpaceAdjust(XMLUtil.getAttributeAsInt(attributes,
                         "twsadjust", 0));
+                setPtr(text, attributes);
                 Area parent = (Area)areaStack.peek();
                 parent.addChildArea(text);
                 areaStack.push(text);
@@ -841,6 +890,7 @@ public class AreaTreeParser {
                 viewport.setContentPosition(XMLUtil.getAttributeAsRectangle2D(attributes, "pos"));
                 viewport.setClip(XMLUtil.getAttributeAsBoolean(attributes, "clip", false));
                 viewport.setOffset(XMLUtil.getAttributeAsInt(attributes, "offset", 0));
+                setPtr(viewport, attributes);
                 Area parent = (Area)areaStack.peek();
                 parent.addChildArea(viewport);
                 areaStack.push(viewport);
@@ -859,6 +909,7 @@ public class AreaTreeParser {
                 transferForeignObjects(attributes, image);
                 setAreaAttributes(attributes, image);
                 setTraits(attributes, image, SUBSET_COMMON);
+                setPtr(image, attributes);
                 getCurrentViewport().setContent(image);
             }
         }
@@ -1143,6 +1194,13 @@ public class AreaTreeParser {
             }
         }
 
+        private void setPtr(Area area, Attributes attributes) {
+            String ptr = attributes.getValue("ptr");
+            if (ptr != null) {
+                area.addTrait(Trait.PTR, ptr);
+            }
+        }
+
         /** {@inheritDoc} */
         public void characters(char[] ch, int start, int length) throws SAXException {
             if (delegate != null) {
index 8e8ae3f1d297ad57d907132bbc41b0123d8a8f1a..d86814d25421a0eebd81ccace7710d295288ebda 100644 (file)
@@ -34,12 +34,14 @@ import javax.xml.transform.sax.TransformerHandler;
 import javax.xml.transform.stream.StreamResult;
 
 import org.w3c.dom.Document;
-
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 import org.xml.sax.SAXException;
 
 import org.apache.xmlgraphics.util.QName;
 import org.apache.xmlgraphics.util.XMLizable;
 
+import org.apache.fop.accessibility.StructureTree;
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.MimeConstants;
@@ -86,6 +88,7 @@ import org.apache.fop.render.Renderer;
 import org.apache.fop.render.RendererContext;
 import org.apache.fop.render.XMLHandler;
 import org.apache.fop.util.ColorUtil;
+import org.apache.fop.util.DOM2SAX;
 
 /**
  * Renderer that renders areas to XML for debugging purposes.
@@ -105,6 +108,8 @@ public class XMLRenderer extends AbstractXMLRenderer {
     /** If not null, the XMLRenderer will mimic another renderer by using its font setup. */
     protected Renderer mimic;
 
+    private int pageSequenceNumber;
+
     /**
      * Creates a new XML renderer.
      */
@@ -440,6 +445,21 @@ public class XMLRenderer extends AbstractXMLRenderer {
         }
         transferForeignObjects(pageSequence);
         startElement("pageSequence", atts);
+        if (this.getUserAgent().isAccessibilityEnabled()) {
+            StructureTree structureTree = getUserAgent().getStructureTree();
+            String structureTreeElement = "structureTree";
+            startElement(structureTreeElement);
+            NodeList nodes = structureTree.getPageSequence(++pageSequenceNumber);
+            for (int i = 0, n = nodes.getLength(); i < n; i++) {
+                Node node = nodes.item(i);
+                try {
+                    new DOM2SAX(handler).writeFragment(node);
+                } catch (SAXException e) {
+                    handleSAXException(e);
+                }
+            }
+            endElement(structureTreeElement);
+        }
         handleExtensionAttachments(pageSequence.getExtensionAttachments());
         LineArea seqTitle = pageSequence.getTitle();
         if (seqTitle != null) {