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;
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();
+ }
+ }
+
}
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;
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;
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;
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;
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) {
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
}
}
+ 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) {
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);
"tlsadjust", 0));
text.setTextWordSpaceAdjust(XMLUtil.getAttributeAsInt(attributes,
"twsadjust", 0));
+ setPtr(text, attributes);
Area parent = (Area)areaStack.peek();
parent.addChildArea(text);
areaStack.push(text);
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);
transferForeignObjects(attributes, image);
setAreaAttributes(attributes, image);
setTraits(attributes, image, SUBSET_COMMON);
+ setPtr(image, attributes);
getCurrentViewport().setContent(image);
}
}
}
}
+ 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) {
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;
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.
/** 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.
*/
}
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) {