From 160d78ce1c348b96e9807f59f3d20bb2226e75c0 Mon Sep 17 00:00:00 2001 From: Peter Hancock Date: Fri, 27 Jan 2012 15:36:05 +0000 Subject: [PATCH] Associate structure tree elements directly to render content * Defer the binding of PCData to struct elems using a placeholder mechanism. * Translate text nodes to marked-content sequences in IF structure tree. * Replace ptr with structure tree element. * Re-order table footers so they appear at the end of the structure tree. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_ImproveAccessibility@1236718 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 1 + .../DummyStructureTreeEventHandler.java | 23 +- .../StructureTree2SAXEventAdapter.java | 35 +- .../StructureTreeElement.java} | 19 +- .../StructureTreeEventHandler.java | 31 +- .../{ => fo}/FO2StructureTreeConverter.java | 390 +------------- .../fop/accessibility/fo/FOEventRecorder.java | 508 ++++++++++++++++++ .../fo/StructureTreeEventTrigger.java | 408 ++++++++++++++ .../org/apache/fop/area/AreaTreeParser.java | 11 - src/java/org/apache/fop/area/Trait.java | 6 +- .../fop/fo/DelegatingFOEventHandler.java | 4 +- .../org/apache/fop/fo/FOEventHandler.java | 10 +- src/java/org/apache/fop/fo/FONode.java | 3 +- src/java/org/apache/fop/fo/FOText.java | 33 +- src/java/org/apache/fop/fo/FOTreeBuilder.java | 2 +- .../fo/extensions/InternalElementMapping.java | 9 +- .../apache/fop/fo/flow/AbstractGraphics.java | 15 +- .../fo/flow/AbstractPageNumberCitation.java | 15 +- .../org/apache/fop/fo/flow/BasicLink.java | 15 +- src/java/org/apache/fop/fo/flow/Block.java | 14 +- .../org/apache/fop/fo/flow/Character.java | 15 +- src/java/org/apache/fop/fo/flow/Inline.java | 14 +- .../org/apache/fop/fo/flow/PageNumber.java | 15 +- .../apache/fop/fo/flow/table/TableFObj.java | 14 +- .../StructureTreeElementHolder.java | 38 ++ .../fop/layoutmgr/BlockLayoutManager.java | 1 - .../org/apache/fop/layoutmgr/TraitSetter.java | 14 +- .../inline/AbstractGraphicsLayoutManager.java | 2 +- ...stractPageNumberCitationLayoutManager.java | 2 +- .../inline/BasicLinkLayoutManager.java | 2 +- .../inline/CharacterLayoutManager.java | 2 +- .../inline/PageNumberLayoutManager.java | 8 +- .../layoutmgr/inline/TextLayoutManager.java | 18 +- .../org/apache/fop/pdf/PDFStructElem.java | 102 +++- .../fop/render/intermediate/IFContext.java | 33 +- .../fop/render/intermediate/IFParser.java | 56 +- .../fop/render/intermediate/IFRenderer.java | 21 +- .../fop/render/intermediate/IFSerializer.java | 29 +- .../intermediate/IFStructureTreeBuilder.java | 118 ++-- .../extensions/AbstractAction.java | 14 +- .../extensions/DocumentNavigationHandler.java | 24 +- .../pdf/PDFDocumentNavigationHandler.java | 8 +- .../pdf/PDFLogicalStructureHandler.java | 84 +-- .../org/apache/fop/render/pdf/PDFPainter.java | 21 +- .../render/pdf/PDFStructureTreeBuilder.java | 71 ++- .../org/apache/fop/render/rtf/RTFHandler.java | 12 +- .../background-image_jpg_repeat.fo | 4 +- .../background-image_jpg_single.fo | 4 +- .../background-image_png_repeat.fo | 4 +- .../background-image_png_single.fo | 4 +- .../background-image_svg_repeat.fo | 4 +- .../background-image_svg_single.fo | 4 +- test/accessibility/complete.fo | 6 +- test/accessibility/image_jpg.fo | 4 +- test/accessibility/image_png.fo | 4 +- test/accessibility/image_svg.fo | 4 +- test/accessibility/image_wmf.fo | 4 +- test/accessibility/leader.fo | 4 +- test/accessibility/links.fo | 4 +- .../pdf/background-image_jpg_repeat.pdf | Bin 12814 -> 12806 bytes .../pdf/background-image_jpg_single.pdf | Bin 12653 -> 12645 bytes .../pdf/background-image_png_repeat.pdf | Bin 35437 -> 35429 bytes .../pdf/background-image_png_single.pdf | Bin 58317 -> 58309 bytes .../pdf/background-image_svg_repeat.pdf | Bin 17104 -> 17096 bytes .../pdf/background-image_svg_single.pdf | Bin 9943 -> 9935 bytes test/accessibility/pdf/complete.pdf | Bin 96730 -> 96722 bytes test/accessibility/pdf/image_jpg.pdf | Bin 9078 -> 9070 bytes test/accessibility/pdf/image_png.pdf | Bin 57788 -> 57780 bytes test/accessibility/pdf/image_svg.pdf | Bin 14292 -> 14284 bytes test/accessibility/pdf/image_wmf.pdf | Bin 208454 -> 304960 bytes test/accessibility/pdf/leader.pdf | Bin 9379 -> 9371 bytes test/accessibility/pdf/links.pdf | Bin 9712 -> 9704 bytes test/accessibility/pdf/role.pdf | Bin 18976 -> 18968 bytes test/accessibility/pdf/role_non-standard.pdf | Bin 18990 -> 18982 bytes test/accessibility/pdf/text_1.pdf | Bin 7504 -> 7496 bytes test/accessibility/pdf/text_2.pdf | Bin 10346 -> 10338 bytes .../accessibility/pdf/text_font-embedding.pdf | Bin 19785 -> 19777 bytes test/accessibility/role.fo | 4 +- test/accessibility/role_non-standard.fo | 4 +- test/accessibility/text_1.fo | 4 +- test/accessibility/text_2.fo | 4 +- test/accessibility/text_font-embedding.fo | 4 +- .../fop/accessibility/fo/DOMResultUtil.java | 54 ++ .../FO2StructureTreeConverterTestCase.java | 109 ++-- .../{ => fo}/fo2StructureTree.xsl | 23 +- .../fop/accessibility/fo/table-footers.fo | 195 +++++++ .../fo/wrapCompleteDocumentInTableFooter.xsl | 66 +++ .../IFStructureTreeBuilderTestCase.java | 2 +- 88 files changed, 1968 insertions(+), 845 deletions(-) rename src/java/org/apache/fop/{fo/properties/StructurePointerPropertySet.java => accessibility/StructureTreeElement.java} (65%) rename src/java/org/apache/fop/accessibility/{ => fo}/FO2StructureTreeConverter.java (53%) create mode 100644 src/java/org/apache/fop/accessibility/fo/FOEventRecorder.java create mode 100644 src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java create mode 100644 src/java/org/apache/fop/fo/properties/StructureTreeElementHolder.java create mode 100644 test/java/org/apache/fop/accessibility/fo/DOMResultUtil.java rename test/java/org/apache/fop/accessibility/{ => fo}/FO2StructureTreeConverterTestCase.java (68%) rename test/java/org/apache/fop/accessibility/{ => fo}/fo2StructureTree.xsl (84%) create mode 100644 test/java/org/apache/fop/accessibility/fo/table-footers.fo create mode 100644 test/java/org/apache/fop/accessibility/fo/wrapCompleteDocumentInTableFooter.xsl diff --git a/build.xml b/build.xml index dda6493ae..8bc66cd95 100644 --- a/build.xml +++ b/build.xml @@ -581,6 +581,7 @@ list of possible build targets. + diff --git a/src/java/org/apache/fop/accessibility/DummyStructureTreeEventHandler.java b/src/java/org/apache/fop/accessibility/DummyStructureTreeEventHandler.java index 80a011bab..07daf2f73 100644 --- a/src/java/org/apache/fop/accessibility/DummyStructureTreeEventHandler.java +++ b/src/java/org/apache/fop/accessibility/DummyStructureTreeEventHandler.java @@ -33,20 +33,31 @@ public final class DummyStructureTreeEventHandler implements StructureTreeEventH private DummyStructureTreeEventHandler() { } - /** {@inheritDoc} */ public void startPageSequence(Locale locale) { } - /** {@inheritDoc} */ - public void startNode(String name, Attributes attributes) { + public void endPageSequence() { + } + + public StructureTreeElement startNode(String name, Attributes attributes) { + return null; } - /** {@inheritDoc} */ public void endNode(String name) { } - /** {@inheritDoc} */ - public void endPageSequence() { + public StructureTreeElement startImageNode(String name, Attributes attributes) { + return null; + } + + public void endImageNode(String name) { + } + + public StructureTreeElement startReferencedNode(String name, Attributes attributes) { + return null; + } + + public void endReferencedNode(String name) { } } diff --git a/src/java/org/apache/fop/accessibility/StructureTree2SAXEventAdapter.java b/src/java/org/apache/fop/accessibility/StructureTree2SAXEventAdapter.java index 240c384d6..2cd92a5ce 100644 --- a/src/java/org/apache/fop/accessibility/StructureTree2SAXEventAdapter.java +++ b/src/java/org/apache/fop/accessibility/StructureTree2SAXEventAdapter.java @@ -50,7 +50,6 @@ public final class StructureTree2SAXEventAdapter implements StructureTreeEventHa return new StructureTree2SAXEventAdapter(contentHandler); } - /** {@inheritDoc} */ public void startPageSequence(Locale locale) { try { @@ -66,7 +65,6 @@ public final class StructureTree2SAXEventAdapter implements StructureTreeEventHa } } - /** {@inheritDoc} */ public void endPageSequence() { try { contentHandler.endElement(IFConstants.NAMESPACE, IFConstants.EL_STRUCTURE_TREE, @@ -81,18 +79,23 @@ public final class StructureTree2SAXEventAdapter implements StructureTreeEventHa } } - /** {@inheritDoc} */ - public void startNode(String name, Attributes attributes) { + public StructureTreeElement startNode(String name, Attributes attributes) { try { - contentHandler.startElement(FOElementMapping.URI, name, - FOElementMapping.STANDARD_PREFIX + ":" + name, - attributes); + if (name.equals("#PCDATA")) { + name = "marked-content"; + contentHandler.startElement(IFConstants.NAMESPACE, name, + name, attributes); + } else { + contentHandler.startElement(FOElementMapping.URI, name, + FOElementMapping.STANDARD_PREFIX + ":" + name, + attributes); + } + return null; } catch (SAXException e) { throw new RuntimeException(e); } } - /** {@inheritDoc} */ public void endNode(String name) { try { contentHandler.endElement(FOElementMapping.URI, name, @@ -101,4 +104,20 @@ public final class StructureTree2SAXEventAdapter implements StructureTreeEventHa throw new RuntimeException(e); } } + + public StructureTreeElement startImageNode(String name, Attributes attributes) { + return startNode(name, attributes); + } + + public void endImageNode(String name) { + endNode(name); + } + + public StructureTreeElement startReferencedNode(String name, Attributes attributes) { + return startNode(name, attributes); + } + + public void endReferencedNode(String name) { + endNode(name); + } } diff --git a/src/java/org/apache/fop/fo/properties/StructurePointerPropertySet.java b/src/java/org/apache/fop/accessibility/StructureTreeElement.java similarity index 65% rename from src/java/org/apache/fop/fo/properties/StructurePointerPropertySet.java rename to src/java/org/apache/fop/accessibility/StructureTreeElement.java index 5cce2822e..3a691c42c 100644 --- a/src/java/org/apache/fop/fo/properties/StructurePointerPropertySet.java +++ b/src/java/org/apache/fop/accessibility/StructureTreeElement.java @@ -17,18 +17,15 @@ /* $Id$ */ -package org.apache.fop.fo.properties; - /** - * Defines property access methods for internal structure pointer extension properties. + * */ -public interface StructurePointerPropertySet { - - /** - * Returns the value of the "foi:ptr" property, the internal structure pointer used - * for tagged PDF and other formats that support a structure tree in addition to paged content. - * @return the "foi:ptr" property - */ - String getPtr(); +package org.apache.fop.accessibility; +/** + * An object that represents the structure of the document in the output format. + * In PDF, an implementation of this interface will typically result into the + * creation of a structure element dictionary (a dictionary of type StructElem). + */ +public interface StructureTreeElement { } diff --git a/src/java/org/apache/fop/accessibility/StructureTreeEventHandler.java b/src/java/org/apache/fop/accessibility/StructureTreeEventHandler.java index d84d07870..4b94d61f1 100644 --- a/src/java/org/apache/fop/accessibility/StructureTreeEventHandler.java +++ b/src/java/org/apache/fop/accessibility/StructureTreeEventHandler.java @@ -32,23 +32,46 @@ public interface StructureTreeEventHandler { /** * Starts a page sequence structure tree node. + * * @param locale The locale of the page sequence */ void startPageSequence(Locale locale); /** * Starts a structure tree node. - * @param name The name of the structure tree node - * @param attributes Map of node properties + * + * @param name the name of the structure tree node + * @param attributes the node properties + * @return the corresponding structure tree element */ - void startNode(String name, Attributes attributes); + StructureTreeElement startNode(String name, Attributes attributes); /** * Ends a structure tree node. - * @param name The name of the structure tree node + * + * @param name the name of the structure tree node */ void endNode(String name); + /** + * Starts an image node. + * + * @param name the name of the structure tree node + * @param attributes the node properties + * @return the corresponding structure tree element + */ + StructureTreeElement startImageNode(String name, Attributes attributes); + + /** + * Starts a node that can be referenced by other nodes. This is usually a + * node that can have Marked Content References as children. + * + * @param name the name of the structure tree node + * @param attributes the node properties + * @return the corresponding structure tree element + */ + StructureTreeElement startReferencedNode(String name, Attributes attributes); + /** * Ends a page sequence structure tree node. */ diff --git a/src/java/org/apache/fop/accessibility/FO2StructureTreeConverter.java b/src/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java similarity index 53% rename from src/java/org/apache/fop/accessibility/FO2StructureTreeConverter.java rename to src/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java index e6d0193b9..47c227e9a 100644 --- a/src/java/org/apache/fop/accessibility/FO2StructureTreeConverter.java +++ b/src/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java @@ -17,21 +17,17 @@ /* $Id$ */ -package org.apache.fop.accessibility; +package org.apache.fop.accessibility.fo; -import java.util.Locale; +import java.util.Stack; import org.xml.sax.SAXException; -import org.xml.sax.helpers.AttributesImpl; -import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.accessibility.StructureTreeEventHandler; import org.apache.fop.fo.DelegatingFOEventHandler; import org.apache.fop.fo.FOEventHandler; -import org.apache.fop.fo.FONode; -import org.apache.fop.fo.extensions.ExtensionElementMapping; +import org.apache.fop.fo.FOText; import org.apache.fop.fo.extensions.ExternalDocument; -import org.apache.fop.fo.extensions.InternalElementMapping; -import org.apache.fop.fo.flow.AbstractGraphics; import org.apache.fop.fo.flow.BasicLink; import org.apache.fop.fo.flow.Block; import org.apache.fop.fo.flow.BlockContainer; @@ -61,8 +57,6 @@ import org.apache.fop.fo.pagination.Flow; import org.apache.fop.fo.pagination.PageSequence; import org.apache.fop.fo.pagination.Root; import org.apache.fop.fo.pagination.StaticContent; -import org.apache.fop.fo.properties.CommonAccessibilityHolder; -import org.apache.fop.util.XMLUtil; /** * Allows to create the structure tree of an FO document, by converting FO @@ -70,354 +64,18 @@ import org.apache.fop.util.XMLUtil; */ public class FO2StructureTreeConverter extends DelegatingFOEventHandler { - private int idCounter; - - /** Delegates to either {@link #foToStructureTreeEventAdapter} or {@link #eventSwallower}. */ + /** The top of the {@link converters} stack. */ private FOEventHandler converter; - private final FOEventHandler foToStructureTreeEventAdapter; - - /** The descendants of some elements like fo:leader must be ignored. */ - private final FOEventHandler eventSwallower; - - private final StructureTreeEventHandler structureTreeEventHandler; - - private final class FOToStructureTreeEventAdapter extends FOEventHandler { - - public FOToStructureTreeEventAdapter(FOUserAgent foUserAgent) { - super(foUserAgent); - } - - @Override - public void startDocument() throws SAXException { - } - - @Override - public void endDocument() throws SAXException { - } - - @Override - public void startPageSequence(PageSequence pageSeq) { - Locale locale = null; - if (pageSeq.getLanguage() != null) { - if (pageSeq.getCountry() != null) { - locale = new Locale(pageSeq.getLanguage(), pageSeq.getCountry()); - } else { - locale = new Locale(pageSeq.getLanguage()); - } - } - structureTreeEventHandler.startPageSequence(locale); - } - - @Override - public void endPageSequence(PageSequence pageSeq) { - structureTreeEventHandler.endPageSequence(); - } - - @Override - public void startPageNumber(PageNumber pagenum) { - startElementWithID(pagenum); - } - - @Override - public void endPageNumber(PageNumber pagenum) { - endElement(pagenum); - } - - @Override - public void startPageNumberCitation(PageNumberCitation pageCite) { - startElementWithID(pageCite); - } - - @Override - public void endPageNumberCitation(PageNumberCitation pageCite) { - endElement(pageCite); - } - - @Override - public void startPageNumberCitationLast(PageNumberCitationLast pageLast) { - startElementWithID(pageLast); - } - - @Override - public void endPageNumberCitationLast(PageNumberCitationLast pageLast) { - endElement(pageLast); - } - - @Override - public void startFlow(Flow fl) { - startElement(fl); - } - - @Override - public void endFlow(Flow fl) { - endElement(fl); - } - - @Override - public void startBlock(Block bl) { - startElementWithID(bl); - } - - @Override - public void endBlock(Block bl) { - endElement(bl); - } + private final Stack converters = new Stack(); - @Override - public void startBlockContainer(BlockContainer blc) { - startElement(blc); - } + private final Stack tableFooterRecorders = new Stack(); - @Override - public void endBlockContainer(BlockContainer blc) { - endElement(blc); - } + private final FOEventHandler structureTreeEventTrigger; - @Override - public void startInline(Inline inl) { - startElementWithID(inl); - } - - @Override - public void endInline(Inline inl) { - endElement(inl); - } - - @Override - public void startTable(Table tbl) { - startElementWithID(tbl); - } - - @Override - public void endTable(Table tbl) { - endElement(tbl); - } - - @Override - public void startHeader(TableHeader header) { - startElementWithID(header); - } - - @Override - public void endHeader(TableHeader header) { - endElement(header); - } - - @Override - public void startFooter(TableFooter footer) { - startElementWithID(footer); - } - - @Override - public void endFooter(TableFooter footer) { - endElement(footer); - } - - @Override - public void startBody(TableBody body) { - startElementWithID(body); - } - - @Override - public void endBody(TableBody body) { - endElement(body); - } - - @Override - public void startRow(TableRow tr) { - startElementWithID(tr); - } - - @Override - public void endRow(TableRow tr) { - endElement(tr); - } - - @Override - public void startCell(TableCell tc) { - AttributesImpl attributes = new AttributesImpl(); - int colSpan = tc.getNumberColumnsSpanned(); - if (colSpan > 1) { - addNoNamespaceAttribute(attributes, "number-columns-spanned", - Integer.toString(colSpan)); - } - startElementWithID(tc, attributes); - } - - @Override - public void endCell(TableCell tc) { - endElement(tc); - } - - @Override - public void startList(ListBlock lb) { - startElement(lb); - } - - @Override - public void endList(ListBlock lb) { - endElement(lb); - } - - @Override - public void startListItem(ListItem li) { - startElement(li); - } - - @Override - public void endListItem(ListItem li) { - endElement(li); - } - - @Override - public void startListLabel(ListItemLabel listItemLabel) { - startElement(listItemLabel); - } - - @Override - public void endListLabel(ListItemLabel listItemLabel) { - endElement(listItemLabel); - } - - @Override - public void startListBody(ListItemBody listItemBody) { - startElement(listItemBody); - } - - @Override - public void endListBody(ListItemBody listItemBody) { - endElement(listItemBody); - } - - @Override - public void startStatic(StaticContent staticContent) { - startElement(staticContent); - } - - @Override - public void endStatic(StaticContent statisContent) { - endElement(statisContent); - } - - @Override - public void startLink(BasicLink basicLink) { - startElementWithID(basicLink); - } - - @Override - public void endLink(BasicLink basicLink) { - endElement(basicLink); - } - - @Override - public void image(ExternalGraphic eg) { - startElementWithIDAndAltText(eg); - endElement(eg); - } - - @Override - public void startInstreamForeignObject(InstreamForeignObject ifo) { - startElementWithIDAndAltText(ifo); - } - - @Override - public void endInstreamForeignObject(InstreamForeignObject ifo) { - endElement(ifo); - } - - @Override - public void startFootnote(Footnote footnote) { - startElement(footnote); - } - - @Override - public void endFootnote(Footnote footnote) { - endElement(footnote); - } - - @Override - public void startFootnoteBody(FootnoteBody body) { - startElement(body); - } - - @Override - public void endFootnoteBody(FootnoteBody body) { - endElement(body); - } - - @Override - public void startWrapper(Wrapper wrapper) { - startElement(wrapper); - } - - @Override - public void endWrapper(Wrapper wrapper) { - endElement(wrapper); - } - - @Override - public void character(Character c) { - startElementWithID(c); - endElement(c); - } - - - private void startElement(FONode node) { - startElement(node, new AttributesImpl()); - } - - private void startElementWithID(FONode node) { - startElementWithID(node, new AttributesImpl()); - } - - private void startElementWithIDAndAltText(AbstractGraphics node) { - AttributesImpl attributes = new AttributesImpl(); - addAttribute(attributes, ExtensionElementMapping.URI, "alt-text", - ExtensionElementMapping.STANDARD_PREFIX, node.getAltText()); - startElementWithID(node, attributes); - } - - private void startElementWithID(FONode node, AttributesImpl attributes) { - String id = Integer.toHexString(idCounter++); - node.setPtr(id); - addAttribute(attributes, - InternalElementMapping.URI, "ptr", InternalElementMapping.STANDARD_PREFIX, id); - startElement(node, attributes); - } - - private void startElement(FONode node, AttributesImpl attributes) { - String localName = node.getLocalName(); - if (node instanceof CommonAccessibilityHolder) { - addRole((CommonAccessibilityHolder) node, attributes); - } - structureTreeEventHandler.startNode(localName, attributes); - } - - private void addNoNamespaceAttribute(AttributesImpl attributes, String name, String value) { - attributes.addAttribute("", name, name, XMLUtil.CDATA, value); - } - - private void addAttribute(AttributesImpl attributes, - String namespace, String localName, String prefix, String value) { - assert namespace.length() > 0 && prefix.length() > 0; - String qualifiedName = prefix + ":" + localName; - attributes.addAttribute(namespace, localName, qualifiedName, XMLUtil.CDATA, value); - } - - private void addRole(CommonAccessibilityHolder node, AttributesImpl attributes) { - String role = node.getCommonAccessibility().getRole(); - if (role != null) { - addNoNamespaceAttribute(attributes, "role", role); - } - } - - private void endElement(FONode node) { - String localName = node.getLocalName(); - structureTreeEventHandler.endNode(localName); - } - - } + /** The descendants of some elements like fo:leader must be ignored. */ + private final FOEventHandler eventSwallower = new FOEventHandler() { + }; /** * Creates a new instance. @@ -428,10 +86,8 @@ public class FO2StructureTreeConverter extends DelegatingFOEventHandler { public FO2StructureTreeConverter(StructureTreeEventHandler structureTreeEventHandler, FOEventHandler delegate) { super(delegate); - this.structureTreeEventHandler = structureTreeEventHandler; - this.foToStructureTreeEventAdapter = new FOToStructureTreeEventAdapter(foUserAgent); - this.converter = foToStructureTreeEventAdapter; - this.eventSwallower = new FOEventHandler(foUserAgent) { }; + this.structureTreeEventTrigger = new StructureTreeEventTrigger(structureTreeEventHandler); + this.converter = structureTreeEventTrigger; } @Override @@ -557,11 +213,16 @@ public class FO2StructureTreeConverter extends DelegatingFOEventHandler { @Override public void startTable(Table tbl) { converter.startTable(tbl); + tableFooterRecorders.push(null); super.startTable(tbl); } @Override public void endTable(Table tbl) { + FOEventRecorder tableFooterRecorder = tableFooterRecorders.pop(); + if (tableFooterRecorder != null) { + tableFooterRecorder.replay(converter); + } converter.endTable(tbl); super.endTable(tbl); } @@ -592,6 +253,8 @@ public class FO2StructureTreeConverter extends DelegatingFOEventHandler { @Override public void startFooter(TableFooter footer) { + converters.push(converter); + converter = new FOEventRecorder(); converter.startFooter(footer); super.startFooter(footer); } @@ -599,6 +262,10 @@ public class FO2StructureTreeConverter extends DelegatingFOEventHandler { @Override public void endFooter(TableFooter footer) { converter.endFooter(footer); + /* Replace the dummy table footer with the real one. */ + tableFooterRecorders.pop(); + tableFooterRecorders.push((FOEventRecorder) converter); + converter = converters.pop(); super.endFooter(footer); } @@ -772,6 +439,7 @@ public class FO2StructureTreeConverter extends DelegatingFOEventHandler { @Override public void startLeader(Leader l) { + converters.push(converter); converter = eventSwallower; converter.startLeader(l); super.startLeader(l); @@ -780,7 +448,7 @@ public class FO2StructureTreeConverter extends DelegatingFOEventHandler { @Override public void endLeader(Leader l) { converter.endLeader(l); - converter = foToStructureTreeEventAdapter; + converter = converters.pop(); super.endLeader(l); } @@ -803,9 +471,9 @@ public class FO2StructureTreeConverter extends DelegatingFOEventHandler { } @Override - public void characters(char[] data, int start, int length) { - converter.characters(data, start, length); - super.characters(data, start, length); + public void characters(FOText foText) { + converter.characters(foText); + super.characters(foText); } @Override diff --git a/src/java/org/apache/fop/accessibility/fo/FOEventRecorder.java b/src/java/org/apache/fop/accessibility/fo/FOEventRecorder.java new file mode 100644 index 000000000..b2b18046d --- /dev/null +++ b/src/java/org/apache/fop/accessibility/fo/FOEventRecorder.java @@ -0,0 +1,508 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.accessibility.fo; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.fop.fo.FOEventHandler; +import org.apache.fop.fo.FOText; +import org.apache.fop.fo.flow.BasicLink; +import org.apache.fop.fo.flow.Block; +import org.apache.fop.fo.flow.BlockContainer; +import org.apache.fop.fo.flow.Character; +import org.apache.fop.fo.flow.ExternalGraphic; +import org.apache.fop.fo.flow.Footnote; +import org.apache.fop.fo.flow.FootnoteBody; +import org.apache.fop.fo.flow.Inline; +import org.apache.fop.fo.flow.InstreamForeignObject; +import org.apache.fop.fo.flow.Leader; +import org.apache.fop.fo.flow.ListBlock; +import org.apache.fop.fo.flow.ListItem; +import org.apache.fop.fo.flow.ListItemBody; +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.Wrapper; +import org.apache.fop.fo.flow.table.Table; +import org.apache.fop.fo.flow.table.TableBody; +import org.apache.fop.fo.flow.table.TableCell; +import org.apache.fop.fo.flow.table.TableColumn; +import org.apache.fop.fo.flow.table.TableFooter; +import org.apache.fop.fo.flow.table.TableHeader; +import org.apache.fop.fo.flow.table.TableRow; + +final class FOEventRecorder extends FOEventHandler { + + private interface Event { + void replay(FOEventHandler target); + } + + private final List events = new ArrayList(); + + public void replay(FOEventHandler target) { + for (Event event : events) { + event.replay(target); + } + } + + @Override + public void startPageNumber(final PageNumber pagenum) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startPageNumber(pagenum); + } + }); + } + + @Override + public void endPageNumber(final PageNumber pagenum) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endPageNumber(pagenum); + } + }); + } + + @Override + public void startPageNumberCitation(final PageNumberCitation pageCite) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startPageNumberCitation(pageCite); + } + }); + } + + @Override + public void endPageNumberCitation(final PageNumberCitation pageCite) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endPageNumberCitation(pageCite); + } + }); + } + + @Override + public void startPageNumberCitationLast(final PageNumberCitationLast pageLast) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startPageNumberCitationLast(pageLast); + } + }); + } + + @Override + public void endPageNumberCitationLast(final PageNumberCitationLast pageLast) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endPageNumberCitationLast(pageLast); + } + }); + } + + @Override + public void startBlock(final Block bl) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startBlock(bl); + } + }); + } + + @Override + public void endBlock(final Block bl) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endBlock(bl); + } + }); + } + + @Override + public void startBlockContainer(final BlockContainer blc) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startBlockContainer(blc); + } + }); + } + + @Override + public void endBlockContainer(final BlockContainer blc) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endBlockContainer(blc); + } + }); + } + + @Override + public void startInline(final Inline inl) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startInline(inl); + } + }); + } + + @Override + public void endInline(final Inline inl) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endInline(inl); + } + }); + } + + @Override + public void startTable(final Table tbl) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startTable(tbl); + } + }); + } + + @Override + public void endTable(final Table tbl) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endTable(tbl); + } + }); + } + + @Override + public void startColumn(final TableColumn tc) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startColumn(tc); + } + }); + } + + @Override + public void endColumn(final TableColumn tc) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endColumn(tc); + } + }); + } + + @Override + public void startHeader(final TableHeader header) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startHeader(header); + } + }); + } + + @Override + public void endHeader(final TableHeader header) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endHeader(header); + } + }); + } + + @Override + public void startFooter(final TableFooter footer) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startFooter(footer); + } + }); + } + + @Override + public void endFooter(final TableFooter footer) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endFooter(footer); + } + }); + } + + @Override + public void startBody(final TableBody body) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startBody(body); + } + }); + } + + @Override + public void endBody(final TableBody body) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endBody(body); + } + }); + } + + @Override + public void startRow(final TableRow tr) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startRow(tr); + } + }); + } + + @Override + public void endRow(final TableRow tr) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endRow(tr); + } + }); + } + + @Override + public void startCell(final TableCell tc) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startCell(tc); + } + }); + } + + @Override + public void endCell(final TableCell tc) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endCell(tc); + } + }); + } + + @Override + public void startList(final ListBlock lb) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startList(lb); + } + }); + } + + @Override + public void endList(final ListBlock lb) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endList(lb); + } + }); + } + + @Override + public void startListItem(final ListItem li) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startListItem(li); + } + }); + } + + @Override + public void endListItem(final ListItem li) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endListItem(li); + } + }); + } + + @Override + public void startListLabel(final ListItemLabel listItemLabel) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startListLabel(listItemLabel); + } + }); + } + + @Override + public void endListLabel(final ListItemLabel listItemLabel) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endListLabel(listItemLabel); + } + }); + } + + @Override + public void startListBody(final ListItemBody listItemBody) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startListBody(listItemBody); + } + }); + } + + @Override + public void endListBody(final ListItemBody listItemBody) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endListBody(listItemBody); + } + }); + } + + @Override + public void startLink(final BasicLink basicLink) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startLink(basicLink); + } + }); + } + + @Override + public void endLink(final BasicLink basicLink) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endLink(basicLink); + } + }); + } + + @Override + public void image(final ExternalGraphic eg) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.image(eg); + } + }); + } + + @Override + public void startInstreamForeignObject(final InstreamForeignObject ifo) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startInstreamForeignObject(ifo); + } + }); + } + + @Override + public void endInstreamForeignObject(final InstreamForeignObject ifo) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endInstreamForeignObject(ifo); + } + }); + } + + @Override + public void startFootnote(final Footnote footnote) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startFootnote(footnote); + } + }); + } + + @Override + public void endFootnote(final Footnote footnote) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endFootnote(footnote); + } + }); + } + + @Override + public void startFootnoteBody(final FootnoteBody body) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startFootnoteBody(body); + } + }); + } + + @Override + public void endFootnoteBody(final FootnoteBody body) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endFootnoteBody(body); + } + }); + } + + @Override + public void startLeader(final Leader l) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startLeader(l); + } + }); + } + + @Override + public void endLeader(final Leader l) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endLeader(l); + } + }); + } + + @Override + public void startWrapper(final Wrapper wrapper) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.startWrapper(wrapper); + } + }); + } + + @Override + public void endWrapper(final Wrapper wrapper) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.endWrapper(wrapper); + } + }); + } + + @Override + public void character(final Character c) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.character(c); + } + }); + } + + @Override + public void characters(final FOText foText) { + events.add(new Event() { + public void replay(FOEventHandler target) { + target.characters(foText); + } + }); + } + +} diff --git a/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java b/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java new file mode 100644 index 000000000..b5cd0a5a4 --- /dev/null +++ b/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java @@ -0,0 +1,408 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.accessibility.fo; + +import java.util.Locale; + +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +import org.apache.fop.accessibility.StructureTreeElement; +import org.apache.fop.accessibility.StructureTreeEventHandler; +import org.apache.fop.fo.FOEventHandler; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FOText; +import org.apache.fop.fo.extensions.ExtensionElementMapping; +import org.apache.fop.fo.flow.AbstractGraphics; +import org.apache.fop.fo.flow.BasicLink; +import org.apache.fop.fo.flow.Block; +import org.apache.fop.fo.flow.BlockContainer; +import org.apache.fop.fo.flow.Character; +import org.apache.fop.fo.flow.ExternalGraphic; +import org.apache.fop.fo.flow.Footnote; +import org.apache.fop.fo.flow.FootnoteBody; +import org.apache.fop.fo.flow.Inline; +import org.apache.fop.fo.flow.InstreamForeignObject; +import org.apache.fop.fo.flow.ListBlock; +import org.apache.fop.fo.flow.ListItem; +import org.apache.fop.fo.flow.ListItemBody; +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.Wrapper; +import org.apache.fop.fo.flow.table.Table; +import org.apache.fop.fo.flow.table.TableBody; +import org.apache.fop.fo.flow.table.TableCell; +import org.apache.fop.fo.flow.table.TableFooter; +import org.apache.fop.fo.flow.table.TableHeader; +import org.apache.fop.fo.flow.table.TableRow; +import org.apache.fop.fo.pagination.Flow; +import org.apache.fop.fo.pagination.PageSequence; +import org.apache.fop.fo.pagination.StaticContent; +import org.apache.fop.fo.properties.CommonAccessibilityHolder; +import org.apache.fop.util.XMLUtil; + +/** + * A bridge between {@link FOEventHandler} and {@link StructureTreeEventHandler}. + */ +class StructureTreeEventTrigger extends FOEventHandler { + + private StructureTreeEventHandler structureTreeEventHandler; + + public StructureTreeEventTrigger(StructureTreeEventHandler structureTreeEventHandler) { + this.structureTreeEventHandler = structureTreeEventHandler; + } + + @Override + public void startDocument() throws SAXException { + } + + @Override + public void endDocument() throws SAXException { + } + + @Override + public void startPageSequence(PageSequence pageSeq) { + Locale locale = null; + if (pageSeq.getLanguage() != null) { + if (pageSeq.getCountry() != null) { + locale = new Locale(pageSeq.getLanguage(), pageSeq.getCountry()); + } else { + locale = new Locale(pageSeq.getLanguage()); + } + } + structureTreeEventHandler.startPageSequence(locale); + } + + @Override + public void endPageSequence(PageSequence pageSeq) { + structureTreeEventHandler.endPageSequence(); + } + + @Override + public void startPageNumber(PageNumber pagenum) { + startElementWithID(pagenum); + } + + @Override + public void endPageNumber(PageNumber pagenum) { + endElement(pagenum); + } + + @Override + public void startPageNumberCitation(PageNumberCitation pageCite) { + startElementWithID(pageCite); + } + + @Override + public void endPageNumberCitation(PageNumberCitation pageCite) { + endElement(pageCite); + } + + @Override + public void startPageNumberCitationLast(PageNumberCitationLast pageLast) { + startElementWithID(pageLast); + } + + @Override + public void endPageNumberCitationLast(PageNumberCitationLast pageLast) { + endElement(pageLast); + } + + @Override + public void startFlow(Flow fl) { + startElement(fl); + } + + @Override + public void endFlow(Flow fl) { + endElement(fl); + } + + @Override + public void startBlock(Block bl) { + startElement(bl); + } + + @Override + public void endBlock(Block bl) { + endElement(bl); + } + + @Override + public void startBlockContainer(BlockContainer blc) { + startElement(blc); + } + + @Override + public void endBlockContainer(BlockContainer blc) { + endElement(blc); + } + + @Override + public void startInline(Inline inl) { + startElement(inl); + } + + @Override + public void endInline(Inline inl) { + endElement(inl); + } + + @Override + public void startTable(Table tbl) { + startElement(tbl); + } + + @Override + public void endTable(Table tbl) { + endElement(tbl); + } + + @Override + public void startHeader(TableHeader header) { + startElement(header); + } + + @Override + public void endHeader(TableHeader header) { + endElement(header); + } + + @Override + public void startFooter(TableFooter footer) { + startElement(footer); + } + + @Override + public void endFooter(TableFooter footer) { + endElement(footer); + } + + @Override + public void startBody(TableBody body) { + startElement(body); + } + + @Override + public void endBody(TableBody body) { + endElement(body); + } + + @Override + public void startRow(TableRow tr) { + startElement(tr); + } + + @Override + public void endRow(TableRow tr) { + endElement(tr); + } + + @Override + public void startCell(TableCell tc) { + AttributesImpl attributes = new AttributesImpl(); + int colSpan = tc.getNumberColumnsSpanned(); + if (colSpan > 1) { + addNoNamespaceAttribute(attributes, "number-columns-spanned", + Integer.toString(colSpan)); + } + startElement(tc, attributes); + } + + @Override + public void endCell(TableCell tc) { + endElement(tc); + } + + @Override + public void startList(ListBlock lb) { + startElement(lb); + } + + @Override + public void endList(ListBlock lb) { + endElement(lb); + } + + @Override + public void startListItem(ListItem li) { + startElement(li); + } + + @Override + public void endListItem(ListItem li) { + endElement(li); + } + + @Override + public void startListLabel(ListItemLabel listItemLabel) { + startElement(listItemLabel); + } + + @Override + public void endListLabel(ListItemLabel listItemLabel) { + endElement(listItemLabel); + } + + @Override + public void startListBody(ListItemBody listItemBody) { + startElement(listItemBody); + } + + @Override + public void endListBody(ListItemBody listItemBody) { + endElement(listItemBody); + } + + @Override + public void startStatic(StaticContent staticContent) { + startElement(staticContent); + } + + @Override + public void endStatic(StaticContent statisContent) { + endElement(statisContent); + } + + @Override + public void startLink(BasicLink basicLink) { + startElementWithID(basicLink); + } + + @Override + public void endLink(BasicLink basicLink) { + endElement(basicLink); + } + + @Override + public void image(ExternalGraphic eg) { + startElementWithIDAndAltText(eg); + endElement(eg); + } + + @Override + public void startInstreamForeignObject(InstreamForeignObject ifo) { + startElementWithIDAndAltText(ifo); + } + + @Override + public void endInstreamForeignObject(InstreamForeignObject ifo) { + endElement(ifo); + } + + @Override + public void startFootnote(Footnote footnote) { + startElement(footnote); + } + + @Override + public void endFootnote(Footnote footnote) { + endElement(footnote); + } + + @Override + public void startFootnoteBody(FootnoteBody body) { + startElement(body); + } + + @Override + public void endFootnoteBody(FootnoteBody body) { + endElement(body); + } + + @Override + public void startWrapper(Wrapper wrapper) { + startElement(wrapper); + } + + @Override + public void endWrapper(Wrapper wrapper) { + endElement(wrapper); + } + + @Override + public void character(Character c) { + startElementWithID(c); + endElement(c); + } + + @Override + public void characters(FOText foText) { + startElementWithID(foText); + endElement(foText); + } + + + private void startElement(FONode node) { + startElement(node, new AttributesImpl()); + } + + private void startElementWithID(FONode node) { + AttributesImpl attributes = new AttributesImpl(); + String localName = node.getLocalName(); + if (node instanceof CommonAccessibilityHolder) { + addRole((CommonAccessibilityHolder) node, attributes); + } + node.setStructureTreeElement(structureTreeEventHandler.startReferencedNode(localName, attributes)); + } + + private void startElementWithIDAndAltText(AbstractGraphics node) { + AttributesImpl attributes = new AttributesImpl(); + String localName = node.getLocalName(); + addRole(node, attributes); + addAttribute(attributes, ExtensionElementMapping.URI, "alt-text", + ExtensionElementMapping.STANDARD_PREFIX, node.getAltText()); + node.setStructureTreeElement(structureTreeEventHandler.startImageNode(localName, attributes)); + } + + private StructureTreeElement startElement(FONode node, AttributesImpl attributes) { + String localName = node.getLocalName(); + if (node instanceof CommonAccessibilityHolder) { + addRole((CommonAccessibilityHolder) node, attributes); + } + return structureTreeEventHandler.startNode(localName, attributes); + } + + private void addNoNamespaceAttribute(AttributesImpl attributes, String name, String value) { + attributes.addAttribute("", name, name, XMLUtil.CDATA, value); + } + + private void addAttribute(AttributesImpl attributes, + String namespace, String localName, String prefix, String value) { + assert namespace.length() > 0 && prefix.length() > 0; + String qualifiedName = prefix + ":" + localName; + attributes.addAttribute(namespace, localName, qualifiedName, XMLUtil.CDATA, value); + } + + private void addRole(CommonAccessibilityHolder node, AttributesImpl attributes) { + String role = node.getCommonAccessibility().getRole(); + if (role != null) { + addNoNamespaceAttribute(attributes, "role", role); + } + } + + private void endElement(FONode node) { + String localName = node.getLocalName(); + structureTreeEventHandler.endNode(localName); + } + +} diff --git a/src/java/org/apache/fop/area/AreaTreeParser.java b/src/java/org/apache/fop/area/AreaTreeParser.java index 545c9015d..29a363495 100644 --- a/src/java/org/apache/fop/area/AreaTreeParser.java +++ b/src/java/org/apache/fop/area/AreaTreeParser.java @@ -728,7 +728,6 @@ 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); @@ -777,7 +776,6 @@ 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); @@ -870,7 +868,6 @@ 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); @@ -889,7 +886,6 @@ public class AreaTreeParser { transferForeignObjects(attributes, image); setAreaAttributes(attributes, image); setTraits(attributes, image, SUBSET_COMMON); - setPtr(image, attributes); getCurrentViewport().setContent(image); } } @@ -1174,13 +1170,6 @@ 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) { diff --git a/src/java/org/apache/fop/area/Trait.java b/src/java/org/apache/fop/area/Trait.java index 042b65337..d9194559d 100644 --- a/src/java/org/apache/fop/area/Trait.java +++ b/src/java/org/apache/fop/area/Trait.java @@ -153,8 +153,8 @@ public final class Trait implements Serializable { /** Trait for color of linethrough decorations when rendering inline parent. */ public static final Integer LINETHROUGH_COLOR = 36; - /** The ptr trait. Used for accessibility */ - public static final Integer PTR = 37; + /** For navigation in the document structure. */ + public static final Integer STRUCTURE_TREE_ELEMENT = 37; /** Maximum value used by trait keys */ public static final int MAX_TRAIT_KEY = 37; @@ -186,7 +186,7 @@ public final class Trait implements Serializable { static { // Create a hashmap mapping trait code to name for external representation //put(ID_LINK, new TraitInfo("id-link", String.class)); - put(PTR, new TraitInfo("ptr", String.class)); + put(STRUCTURE_TREE_ELEMENT, new TraitInfo("structure-tree-element", String.class)); put(INTERNAL_LINK, new TraitInfo("internal-link", InternalLink.class)); put(EXTERNAL_LINK, new TraitInfo("external-link", ExternalLink.class)); put(FONT, new TraitInfo("font", FontTriplet.class)); diff --git a/src/java/org/apache/fop/fo/DelegatingFOEventHandler.java b/src/java/org/apache/fop/fo/DelegatingFOEventHandler.java index ed85bd1c9..e64106a80 100644 --- a/src/java/org/apache/fop/fo/DelegatingFOEventHandler.java +++ b/src/java/org/apache/fop/fo/DelegatingFOEventHandler.java @@ -387,8 +387,8 @@ public abstract class DelegatingFOEventHandler extends FOEventHandler { } @Override - public void characters(char[] data, int start, int length) { - delegate.characters(data, start, length); + public void characters(FOText foText) { + delegate.characters(foText); } @Override diff --git a/src/java/org/apache/fop/fo/FOEventHandler.java b/src/java/org/apache/fop/fo/FOEventHandler.java index 1f3514dea..bed1f3677 100644 --- a/src/java/org/apache/fop/fo/FOEventHandler.java +++ b/src/java/org/apache/fop/fo/FOEventHandler.java @@ -88,6 +88,10 @@ public abstract class FOEventHandler { this.fontInfo.setEventListener(new FontEventAdapter(foUserAgent.getEventBroadcaster())); } + /** Constructor for sub-classes that do not need an {@link FOUserAgent} instance. */ + protected FOEventHandler() { + } + /** * Returns the User Agent object associated with this FOEventHandler. * @return the User Agent object @@ -532,11 +536,9 @@ public abstract class FOEventHandler { /** * Process character data. - * @param data Array of characters to process. - * @param start Offset for characters to process. - * @param length Portion of array to process. + * @param foText text to process */ - public void characters(char[] data, int start, int length) { + public void characters(FOText foText) { } /** diff --git a/src/java/org/apache/fop/fo/FONode.java b/src/java/org/apache/fop/fo/FONode.java index 4946f6d5c..622ff86d4 100644 --- a/src/java/org/apache/fop/fo/FONode.java +++ b/src/java/org/apache/fop/fo/FONode.java @@ -32,6 +32,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.util.QName; +import org.apache.fop.accessibility.StructureTreeElement; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fo.extensions.ExtensionAttachment; @@ -912,7 +913,7 @@ public abstract class FONode implements Cloneable { } - public void setPtr(String ptr) { + public void setStructureTreeElement(StructureTreeElement structureTreeElement) { throw new UnsupportedOperationException(); } diff --git a/src/java/org/apache/fop/fo/FOText.java b/src/java/org/apache/fop/fo/FOText.java index 5db11f731..3858cdea9 100644 --- a/src/java/org/apache/fop/fo/FOText.java +++ b/src/java/org/apache/fop/fo/FOText.java @@ -25,6 +25,7 @@ import java.util.NoSuchElementException; import org.xml.sax.Locator; +import org.apache.fop.accessibility.StructureTreeElement; import org.apache.fop.apps.FOPException; import org.apache.fop.datatypes.Length; import org.apache.fop.fo.flow.Block; @@ -79,6 +80,8 @@ public class FOText extends FONode implements CharSequence { /** Holds the text decoration values. May be null */ private CommonTextDecoration textDecoration; + private StructureTreeElement structureTreeElement; + private static final int IS_WORD_CHAR_FALSE = 0; private static final int IS_WORD_CHAR_TRUE = 1; private static final int IS_WORD_CHAR_MAYBE = 2; @@ -115,25 +118,14 @@ public class FOText extends FONode implements CharSequence { /** * Return the array of characters for this instance. * - * @return a char array containing the text + * @return a char sequence containing the text */ - public char[] getCharArray() { - + public CharSequence getCharSequence() { if (this.charBuffer == null) { return null; } - - if (this.charBuffer.hasArray()) { - return this.charBuffer.array(); - } - - // only if the buffer implementation has - // no accessible backing array, return a new one - char[] ca = new char[this.charBuffer.limit()]; this.charBuffer.rewind(); - this.charBuffer.get(ca); - return ca; - + return this.charBuffer.asReadOnlyBuffer().subSequence(0, this.charBuffer.limit()); } /** {@inheritDoc} */ @@ -176,8 +168,7 @@ public class FOText extends FONode implements CharSequence { /** {@inheritDoc} */ protected void endOfNode() throws FOPException { super.endOfNode(); - getFOEventHandler().characters( - this.getCharArray(), 0, this.charBuffer.limit()); + getFOEventHandler().characters(this); } /** {@inheritDoc} */ @@ -670,4 +661,14 @@ public class FOText extends FONode implements CharSequence { this.charBuffer.rewind(); } } + + @Override + public void setStructureTreeElement(StructureTreeElement structureTreeElement) { + this.structureTreeElement = structureTreeElement; + } + + public StructureTreeElement getStructureTreeElement() { + return structureTreeElement; + } + } diff --git a/src/java/org/apache/fop/fo/FOTreeBuilder.java b/src/java/org/apache/fop/fo/FOTreeBuilder.java index b053692d6..ece4e5448 100644 --- a/src/java/org/apache/fop/fo/FOTreeBuilder.java +++ b/src/java/org/apache/fop/fo/FOTreeBuilder.java @@ -33,7 +33,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.util.QName; -import org.apache.fop.accessibility.FO2StructureTreeConverter; +import org.apache.fop.accessibility.fo.FO2StructureTreeConverter; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.FormattingResults; diff --git a/src/java/org/apache/fop/fo/extensions/InternalElementMapping.java b/src/java/org/apache/fop/fo/extensions/InternalElementMapping.java index e939841e1..687952d25 100644 --- a/src/java/org/apache/fop/fo/extensions/InternalElementMapping.java +++ b/src/java/org/apache/fop/fo/extensions/InternalElementMapping.java @@ -37,11 +37,18 @@ public class InternalElementMapping extends ElementMapping { /** The standard XML prefix for elements and attributes in this namespace. */ public static final String STANDARD_PREFIX = "foi"; + /** The "struct-id" attribute, to identify a structure tree element. */ + public static final String STRUCT_ID = "struct-id"; + + /** The "struct-ref" attribute, to refer to a structure tree element. */ + public static final String STRUCT_REF = "struct-ref"; + private static final Set PROPERTY_ATTRIBUTES = new java.util.HashSet(); static { //These are FOP's extension properties for accessibility - PROPERTY_ATTRIBUTES.add("ptr"); + PROPERTY_ATTRIBUTES.add(STRUCT_ID); + PROPERTY_ATTRIBUTES.add(STRUCT_REF); } /** diff --git a/src/java/org/apache/fop/fo/flow/AbstractGraphics.java b/src/java/org/apache/fop/fo/flow/AbstractGraphics.java index 67a33d088..2b8fa8a0b 100644 --- a/src/java/org/apache/fop/fo/flow/AbstractGraphics.java +++ b/src/java/org/apache/fop/fo/flow/AbstractGraphics.java @@ -19,6 +19,7 @@ package org.apache.fop.fo.flow; +import org.apache.fop.accessibility.StructureTreeElement; import org.apache.fop.apps.FOPException; import org.apache.fop.datatypes.Length; import org.apache.fop.fo.FONode; @@ -31,7 +32,7 @@ import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fo.properties.LengthRangeProperty; import org.apache.fop.fo.properties.SpaceProperty; -import org.apache.fop.fo.properties.StructurePointerPropertySet; +import org.apache.fop.fo.properties.StructureTreeElementHolder; /** * Common base class for the @@ -40,7 +41,7 @@ import org.apache.fop.fo.properties.StructurePointerPropertySet; * fo:external-graphic flow formatting objects. */ public abstract class AbstractGraphics extends FObj - implements GraphicsProperties, StructurePointerPropertySet, CommonAccessibilityHolder { + implements GraphicsProperties, StructureTreeElementHolder, CommonAccessibilityHolder { // The value of properties relevant for fo:instream-foreign-object // and external-graphics. @@ -66,7 +67,7 @@ public abstract class AbstractGraphics extends FObj private int textAlign; private Length width; private String altText; - private String ptr; // used for accessibility + private StructureTreeElement structureTreeElement; // Unused but valid items, commented out for performance: // private CommonAccessibility commonAccessibility; // private CommonAural commonAural; @@ -226,13 +227,13 @@ public abstract class AbstractGraphics extends FObj } @Override - public void setPtr(String ptr) { - this.ptr = ptr; + public void setStructureTreeElement(StructureTreeElement structureTreeElement) { + this.structureTreeElement = structureTreeElement; } /** {@inheritDoc} */ - public String getPtr() { - return ptr; + public StructureTreeElement getStructureTreeElement() { + return structureTreeElement; } public String getAltText() { diff --git a/src/java/org/apache/fop/fo/flow/AbstractPageNumberCitation.java b/src/java/org/apache/fop/fo/flow/AbstractPageNumberCitation.java index bbb632b29..108896d91 100644 --- a/src/java/org/apache/fop/fo/flow/AbstractPageNumberCitation.java +++ b/src/java/org/apache/fop/fo/flow/AbstractPageNumberCitation.java @@ -24,6 +24,7 @@ import java.awt.Color; import org.xml.sax.Attributes; import org.xml.sax.Locator; +import org.apache.fop.accessibility.StructureTreeElement; import org.apache.fop.apps.FOPException; import org.apache.fop.datatypes.Length; import org.apache.fop.fo.Constants; @@ -37,7 +38,7 @@ import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.CommonFont; import org.apache.fop.fo.properties.CommonTextDecoration; import org.apache.fop.fo.properties.SpaceProperty; -import org.apache.fop.fo.properties.StructurePointerPropertySet; +import org.apache.fop.fo.properties.StructureTreeElementHolder; /** * Common base class for the @@ -46,7 +47,7 @@ import org.apache.fop.fo.properties.StructurePointerPropertySet; * fo:page-number-citation-last objects. */ public abstract class AbstractPageNumberCitation extends FObj - implements StructurePointerPropertySet, CommonAccessibilityHolder { + implements StructureTreeElementHolder, CommonAccessibilityHolder { // The value of properties relevant for fo:page-number-citation(-last). private CommonAccessibility commonAccessibility; @@ -56,7 +57,7 @@ public abstract class AbstractPageNumberCitation extends FObj private int alignmentBaseline; private Length baselineShift; private int dominantBaseline; - private String ptr; // used for accessibility + private StructureTreeElement structureTreeElement; // private ToBeImplementedProperty letterSpacing; private SpaceProperty lineHeight; private String refId; @@ -151,13 +152,13 @@ public abstract class AbstractPageNumberCitation extends FObj } @Override - public void setPtr(String ptr) { - this.ptr = ptr; + public void setStructureTreeElement(StructureTreeElement structureTreeElement) { + this.structureTreeElement = structureTreeElement; } /** {@inheritDoc} */ - public String getPtr() { - return ptr; + public StructureTreeElement getStructureTreeElement() { + return structureTreeElement; } /** @return the "alignment-adjust" property */ diff --git a/src/java/org/apache/fop/fo/flow/BasicLink.java b/src/java/org/apache/fop/fo/flow/BasicLink.java index 7bff2d521..0d6d5d9b4 100644 --- a/src/java/org/apache/fop/fo/flow/BasicLink.java +++ b/src/java/org/apache/fop/fo/flow/BasicLink.java @@ -21,12 +21,13 @@ package org.apache.fop.fo.flow; import org.xml.sax.Locator; +import org.apache.fop.accessibility.StructureTreeElement; import org.apache.fop.apps.FOPException; import org.apache.fop.datatypes.Length; import org.apache.fop.fo.FONode; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.ValidationException; -import org.apache.fop.fo.properties.StructurePointerPropertySet; +import org.apache.fop.fo.properties.StructureTreeElementHolder; /** * Class modelling the @@ -36,14 +37,14 @@ import org.apache.fop.fo.properties.StructurePointerPropertySet; * and whether that link is external (uses a URI) or internal (an id * reference). */ -public class BasicLink extends InlineLevel implements StructurePointerPropertySet { +public class BasicLink extends InlineLevel implements StructureTreeElementHolder { // The value of properties relevant for fo:basic-link. private Length alignmentAdjust; private int alignmentBaseline; private Length baselineShift; private int dominantBaseline; - private String ptr; + private StructureTreeElement structureTreeElement; // private ToBeImplementedProperty destinationPlacementOffset; private String externalDestination; // private ToBeImplementedProperty indicateDestination; @@ -143,13 +144,13 @@ public class BasicLink extends InlineLevel implements StructurePointerPropertySe } @Override - public void setPtr(String ptr) { - this.ptr = ptr; + public void setStructureTreeElement(StructureTreeElement structureTreeElement) { + this.structureTreeElement = structureTreeElement; } /** {@inheritDoc} */ - public String getPtr() { - return ptr; + public StructureTreeElement getStructureTreeElement() { + return structureTreeElement; } /** diff --git a/src/java/org/apache/fop/fo/flow/Block.java b/src/java/org/apache/fop/fo/flow/Block.java index b1705288a..4e5b6f15f 100644 --- a/src/java/org/apache/fop/fo/flow/Block.java +++ b/src/java/org/apache/fop/fo/flow/Block.java @@ -42,13 +42,12 @@ import org.apache.fop.fo.properties.CommonMarginBlock; import org.apache.fop.fo.properties.CommonRelativePosition; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fo.properties.SpaceProperty; -import org.apache.fop.fo.properties.StructurePointerPropertySet; /** * Class modelling the * fo:block object. */ -public class Block extends FObjMixed implements BreakPropertySet, StructurePointerPropertySet, +public class Block extends FObjMixed implements BreakPropertySet, CommonAccessibilityHolder { // used for FO validation @@ -77,7 +76,6 @@ public class Block extends FObjMixed implements BreakPropertySet, StructurePoint private int lineHeightShiftAdjustment; private int lineStackingStrategy; private Numeric orphans; - private String ptr; //used for accessibility private int whiteSpaceTreatment; private int span; private int textAlign; @@ -183,16 +181,6 @@ public class Block extends FObjMixed implements BreakPropertySet, StructurePoint return breakAfter; } - @Override - public void setPtr(String ptr) { - this.ptr = ptr; - } - - /** {@inheritDoc} */ - public String getPtr() { - return ptr; - } - /** @return the "break-before" property. */ public int getBreakBefore() { return breakBefore; diff --git a/src/java/org/apache/fop/fo/flow/Character.java b/src/java/org/apache/fop/fo/flow/Character.java index a33bea53d..c4de9fb72 100644 --- a/src/java/org/apache/fop/fo/flow/Character.java +++ b/src/java/org/apache/fop/fo/flow/Character.java @@ -24,6 +24,7 @@ import java.util.NoSuchElementException; import org.xml.sax.Locator; +import org.apache.fop.accessibility.StructureTreeElement; import org.apache.fop.apps.FOPException; import org.apache.fop.datatypes.Length; import org.apache.fop.fo.CharIterator; @@ -38,13 +39,13 @@ import org.apache.fop.fo.properties.CommonTextDecoration; import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fo.properties.Property; import org.apache.fop.fo.properties.SpaceProperty; -import org.apache.fop.fo.properties.StructurePointerPropertySet; +import org.apache.fop.fo.properties.StructureTreeElementHolder; /** * Class modelling the * fo:character object. */ -public class Character extends FObj implements StructurePointerPropertySet { +public class Character extends FObj implements StructureTreeElementHolder { // The value of properties relevant for fo:character. private CommonBorderPaddingBackground commonBorderPaddingBackground; private CommonFont commonFont; @@ -63,7 +64,7 @@ public class Character extends FObj implements StructurePointerPropertySet { private CommonTextDecoration textDecoration; // private ToBeImplementedProperty textShadow; private Property wordSpacing; - private String ptr; // used for accessibility + private StructureTreeElement structureTreeElement; // Unused but valid items, commented out for performance: // private CommonAural commonAural; // private CommonMarginInline commonMarginInline; @@ -210,13 +211,13 @@ public class Character extends FObj implements StructurePointerPropertySet { } @Override - public void setPtr(String ptr) { - this.ptr = ptr; + public void setStructureTreeElement(StructureTreeElement structureTreeElement) { + this.structureTreeElement = structureTreeElement; } /** {@inheritDoc} */ - public String getPtr() { - return ptr; + public StructureTreeElement getStructureTreeElement() { + return structureTreeElement; } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/fo/flow/Inline.java b/src/java/org/apache/fop/fo/flow/Inline.java index e458184f4..debf6bbf6 100644 --- a/src/java/org/apache/fop/fo/flow/Inline.java +++ b/src/java/org/apache/fop/fo/flow/Inline.java @@ -26,19 +26,17 @@ import org.apache.fop.datatypes.Length; import org.apache.fop.fo.FONode; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.ValidationException; -import org.apache.fop.fo.properties.StructurePointerPropertySet; /** * Class modelling the * fo:inline formatting object. */ -public class Inline extends InlineLevel implements StructurePointerPropertySet { +public class Inline extends InlineLevel { // The value of properties relevant for fo:inline. // See also superclass InlineLevel private Length alignmentAdjust; private int alignmentBaseline; private Length baselineShift; - private String ptr; // used for accessibility private int dominantBaseline; // Unused but valid items, commented out for performance: // private CommonRelativePosition commonRelativePosition; @@ -147,16 +145,6 @@ public class Inline extends InlineLevel implements StructurePointerPropertySet { return dominantBaseline; } - @Override - public void setPtr(String ptr) { - this.ptr = ptr; - } - - /** {@inheritDoc} */ - public String getPtr() { - return ptr; - } - /** {@inheritDoc} */ public String getLocalName() { return "inline"; diff --git a/src/java/org/apache/fop/fo/flow/PageNumber.java b/src/java/org/apache/fop/fo/flow/PageNumber.java index c0373aa7f..0e5ce5071 100644 --- a/src/java/org/apache/fop/fo/flow/PageNumber.java +++ b/src/java/org/apache/fop/fo/flow/PageNumber.java @@ -23,6 +23,7 @@ import java.awt.Color; import org.xml.sax.Locator; +import org.apache.fop.accessibility.StructureTreeElement; import org.apache.fop.apps.FOPException; import org.apache.fop.datatypes.Length; import org.apache.fop.fo.Constants; @@ -36,14 +37,14 @@ import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.CommonFont; import org.apache.fop.fo.properties.CommonTextDecoration; import org.apache.fop.fo.properties.SpaceProperty; -import org.apache.fop.fo.properties.StructurePointerPropertySet; +import org.apache.fop.fo.properties.StructureTreeElementHolder; /** * Class modelling the * fo:page-number object. */ public class PageNumber extends FObj - implements StructurePointerPropertySet, CommonAccessibilityHolder { + implements StructureTreeElementHolder, CommonAccessibilityHolder { // The value of properties relevant for fo:page-number. private CommonAccessibility commonAccessibility; private CommonBorderPaddingBackground commonBorderPaddingBackground; @@ -52,7 +53,7 @@ public class PageNumber extends FObj private int alignmentBaseline; private Length baselineShift; private int dominantBaseline; - private String ptr; // used for accessibility + private StructureTreeElement structureTreeElement; // private ToBeImplementedProperty letterSpacing; private SpaceProperty lineHeight; /** Holds the text decoration values. May be null */ @@ -176,13 +177,13 @@ public class PageNumber extends FObj } @Override - public void setPtr(String ptr) { - this.ptr = ptr; + public void setStructureTreeElement(StructureTreeElement structureTreeElement) { + this.structureTreeElement = structureTreeElement; } /** {@inheritDoc} */ - public String getPtr() { - return ptr; + public StructureTreeElement getStructureTreeElement() { + return structureTreeElement; } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/fo/flow/table/TableFObj.java b/src/java/org/apache/fop/fo/flow/table/TableFObj.java index 0da7b9458..2506c26b4 100644 --- a/src/java/org/apache/fop/fo/flow/table/TableFObj.java +++ b/src/java/org/apache/fop/fo/flow/table/TableFObj.java @@ -36,19 +36,17 @@ import org.apache.fop.fo.properties.EnumProperty; import org.apache.fop.fo.properties.NumberProperty; import org.apache.fop.fo.properties.Property; import org.apache.fop.fo.properties.PropertyMaker; -import org.apache.fop.fo.properties.StructurePointerPropertySet; import org.apache.fop.layoutmgr.table.CollapsingBorderModel; /** * Common base class for table-related FOs */ -public abstract class TableFObj extends FObj implements StructurePointerPropertySet { +public abstract class TableFObj extends FObj { private Numeric borderAfterPrecedence; private Numeric borderBeforePrecedence; private Numeric borderEndPrecedence; private Numeric borderStartPrecedence; - private String ptr; ConditionalBorder borderBefore; // CSOK: VisibilityModifier ConditionalBorder borderAfter; // CSOK: VisibilityModifier @@ -240,16 +238,6 @@ public abstract class TableFObj extends FObj implements StructurePointerProperty } } - @Override - public void setPtr(String ptr) { - this.ptr = ptr; - } - - /** {@inheritDoc} */ - public String getPtr() { - return ptr; - } - /** * Prepares the borders of this element if the collapsing-border model is in use. * Conflict resolution with parent elements is done where applicable. diff --git a/src/java/org/apache/fop/fo/properties/StructureTreeElementHolder.java b/src/java/org/apache/fop/fo/properties/StructureTreeElementHolder.java new file mode 100644 index 000000000..6fbb608de --- /dev/null +++ b/src/java/org/apache/fop/fo/properties/StructureTreeElementHolder.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.fo.properties; + +import org.apache.fop.accessibility.StructureTreeElement; + +/** + * Implementations of this interface can return the element in the document's + * structure tree that they resulted into. Used for tagged PDF and other formats + * that support a structure tree in addition to paged content. + */ +public interface StructureTreeElementHolder { + + /** + * Returns the element in the document's structure tree that corresponds to this instance. + * + * @return a structure tree element + */ + StructureTreeElement getStructureTreeElement(); + +} diff --git a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java index b748c2152..ed2ea4ee9 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java @@ -329,7 +329,6 @@ public class BlockLayoutManager extends BlockStackingLayoutManager addMarkersToPage(false, isFirst(firstPos), isLast(lastPos)); - TraitSetter.addPtr(curBlockArea, getBlockFO().getPtr()); // used for accessibility TraitSetter.addSpaceBeforeAfter(curBlockArea, layoutContext.getSpaceAdjust(), effSpaceBefore, effSpaceAfter); flush(); diff --git a/src/java/org/apache/fop/layoutmgr/TraitSetter.java b/src/java/org/apache/fop/layoutmgr/TraitSetter.java index c0e451577..da548c23c 100644 --- a/src/java/org/apache/fop/layoutmgr/TraitSetter.java +++ b/src/java/org/apache/fop/layoutmgr/TraitSetter.java @@ -22,6 +22,7 @@ package org.apache.fop.layoutmgr; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.fop.accessibility.StructureTreeElement; import org.apache.fop.area.Area; import org.apache.fop.area.Trait; import org.apache.fop.datatypes.LengthBase; @@ -29,9 +30,9 @@ import org.apache.fop.datatypes.PercentBaseContext; import org.apache.fop.datatypes.SimplePercentBaseContext; import org.apache.fop.fo.Constants; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; +import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo; import org.apache.fop.fo.properties.CommonMarginBlock; import org.apache.fop.fo.properties.CommonTextDecoration; -import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo; import org.apache.fop.fonts.Font; import org.apache.fop.traits.BorderProps; import org.apache.fop.traits.MinOptMax; @@ -591,13 +592,14 @@ public final class TraitSetter { } /** - * Adds the ptr trait to the area. + * Sets the structure tree element associated to the given area. + * * @param area the area to set the traits on - * @param ptr string + * @param structureTreeElement the element the area is associated to in the document structure */ - public static void addPtr(Area area, String ptr) { - if (ptr != null && ptr.length() > 0) { - area.addTrait(Trait.PTR, ptr); + public static void addStructureTreeElement(Area area, StructureTreeElement structureTreeElement) { + if (structureTreeElement != null) { + area.addTrait(Trait.STRUCTURE_TREE_ELEMENT, structureTreeElement); } } diff --git a/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java index 218497a53..8c797a48c 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java @@ -85,7 +85,7 @@ public abstract class AbstractGraphicsLayoutManager extends LeafNodeLayoutManage transferForeignAttributes(viewportArea); InlineViewport vp = new InlineViewport(viewportArea); - TraitSetter.addPtr(vp, fobj.getPtr()); // used for accessibility + TraitSetter.addStructureTreeElement(vp, fobj.getStructureTreeElement()); TraitSetter.setProducerID(vp, fobj.getId()); vp.setIPD(imageLayout.getViewportSize().width); vp.setBPD(imageLayout.getViewportSize().height); diff --git a/src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java index e090fbae6..8c769924a 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java @@ -136,7 +136,7 @@ public abstract class AbstractPageNumberCitationLayoutManager extends LeafNodeLa text.setBaselineOffset(font.getAscender()); TraitSetter.addFontTraits(text, font); text.addTrait(Trait.COLOR, fobj.getColor()); - TraitSetter.addPtr(text, fobj.getPtr()); // used for accessibility + TraitSetter.addStructureTreeElement(text, fobj.getStructureTreeElement()); TraitSetter.addTextDecoration(text, fobj.getTextDecoration()); } diff --git a/src/java/org/apache/fop/layoutmgr/inline/BasicLinkLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/BasicLinkLayoutManager.java index 40c9a324e..1390c04d8 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/BasicLinkLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/BasicLinkLayoutManager.java @@ -59,7 +59,7 @@ public class BasicLinkLayoutManager extends InlineLayoutManager { private void setupBasicLinkArea(InlineArea area) { BasicLink fobj = (BasicLink) this.fobj; // internal destinations take precedence: - TraitSetter.addPtr(area, fobj.getPtr()); // used for accessibility + TraitSetter.addStructureTreeElement(area, fobj.getStructureTreeElement()); if (fobj.hasInternalDestination()) { String idref = fobj.getInternalDestination(); PageSequenceLayoutManager pslm = getPSLM(); diff --git a/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java index 2178b2e77..4877ff9bd 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java @@ -87,7 +87,7 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager { } TraitSetter.setProducerID(text, node.getId()); TraitSetter.addTextDecoration(text, node.getTextDecoration()); - TraitSetter.addPtr(text, node.getPtr()); // used for accessibility + TraitSetter.addStructureTreeElement(text, node.getStructureTreeElement()); return text; } diff --git a/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java index d8cfe6cda..4b7289b37 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java @@ -19,13 +19,13 @@ package org.apache.fop.layoutmgr.inline; +import org.apache.fop.area.Trait; +import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.area.inline.TextArea; import org.apache.fop.fo.flow.PageNumber; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontTriplet; -import org.apache.fop.area.inline.InlineArea; -import org.apache.fop.area.inline.TextArea; -import org.apache.fop.area.Trait; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.TraitSetter; import org.apache.fop.traits.MinOptMax; @@ -85,7 +85,7 @@ public class PageNumberLayoutManager extends LeafNodeLayoutManager { text.setBaselineOffset(font.getAscender()); TraitSetter.addFontTraits(text, font); text.addTrait(Trait.COLOR, fobj.getColor()); - TraitSetter.addPtr(text, fobj.getPtr()); // used for accessibility + TraitSetter.addStructureTreeElement(text, fobj.getStructureTreeElement()); TraitSetter.addTextDecoration(text, fobj.getTextDecoration()); return text; diff --git a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java index 81240dec0..8767fe296 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java @@ -31,8 +31,6 @@ import org.apache.fop.area.Trait; import org.apache.fop.area.inline.TextArea; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FOText; -import org.apache.fop.fo.FObj; -import org.apache.fop.fo.properties.StructurePointerPropertySet; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontSelector; import org.apache.fop.layoutmgr.InlineKnuthSequence; @@ -438,7 +436,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { setText(); TraitSetter.addFontTraits(textArea, font); textArea.addTrait(Trait.COLOR, foText.getColor()); - TraitSetter.addPtr(textArea, getPtr()); // used for accessibility + TraitSetter.addStructureTreeElement(textArea, foText.getStructureTreeElement()); TraitSetter.addTextDecoration(textArea, foText.getTextDecoration()); TraitSetter.addFontTraits(textArea, font); return textArea; @@ -577,20 +575,6 @@ public class TextLayoutManager extends LeafNodeLayoutManager { } } - /** - * used for accessibility - * @return ptr of fobj - */ - private String getPtr() { - FObj fobj = parentLayoutManager.getFObj(); - if (fobj instanceof StructurePointerPropertySet) { - return (((StructurePointerPropertySet) fobj).getPtr()); - } else { - //No structure pointer applicable - return null; - } - } - private AreaInfo getAreaInfo(int index) { return (AreaInfo) areaInfos.get(index); } diff --git a/src/java/org/apache/fop/pdf/PDFStructElem.java b/src/java/org/apache/fop/pdf/PDFStructElem.java index 6dfb0dc95..44622638d 100644 --- a/src/java/org/apache/fop/pdf/PDFStructElem.java +++ b/src/java/org/apache/fop/pdf/PDFStructElem.java @@ -19,17 +19,28 @@ package org.apache.fop.pdf; +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; +import java.util.ArrayList; +import java.util.List; import java.util.Locale; +import org.apache.fop.accessibility.StructureTreeElement; import org.apache.fop.util.LanguageTags; /** * Class representing a PDF Structure Element. */ -public class PDFStructElem extends PDFDictionary { +public class PDFStructElem extends PDFDictionary implements StructureTreeElement { private PDFStructElem parentElement; + /** + * Elements to be added to the kids array. + */ + protected List kids; + /** * Creates a new structure element. * @@ -57,20 +68,11 @@ public class PDFStructElem extends PDFDictionary { /** {@inheritDoc} */ public void setParent(PDFObject parent) { - if (parent != null) { + if (parent != null && parent.hasObjectNumber()) { put("P", new PDFReference(parent)); } } - /** - * Returns the kids of this structure element. - * - * @return the value of the K entry - */ - private PDFArray getKids() { - return (PDFArray) get("K"); - } - /** * Add a kid to this structure element. This element will then add itself to * its parent structure element if it has not already, and so will the @@ -79,24 +81,10 @@ public class PDFStructElem extends PDFDictionary { * @param kid element to be added */ public void addKid(PDFObject kid) { - PDFArray kids = getKids(); if (kids == null) { - kids = new PDFArray(); - put("K", kids); + kids = new ArrayList(); } kids.add(kid); - joinHierarchy(); - } - - private boolean containsKid(PDFObject kid) { - PDFArray kids = getKids(); - return kids != null && kids.contains(kid); - } - - private void joinHierarchy() { - if (parentElement != null && !parentElement.containsKid(this)) { - parentElement.addKid(this); - } } /** @@ -109,7 +97,6 @@ public class PDFStructElem extends PDFDictionary { */ public void setMCIDKid(int mcid) { put("K", mcid); - joinHierarchy(); } /** @@ -127,7 +114,7 @@ public class PDFStructElem extends PDFDictionary { * @return the value of the S entry */ public PDFName getStructureType() { - return (PDFName)get("S"); + return (PDFName) get("S"); } /** @@ -154,6 +141,63 @@ public class PDFStructElem extends PDFDictionary { * @return the value of the Lang entry (null if no language was specified) */ public String getLanguage() { - return (String)get("Lang"); + return (String) get("Lang"); + } + + @Override + protected void writeDictionary(OutputStream out, Writer writer) throws IOException { + attachKids(); + super.writeDictionary(out, writer); + } + + /** + * Attaches all valid kids to the kids array. + * + * @return true iff 1+ kids were added to the kids array + */ + protected boolean attachKids() { + List validKids = new ArrayList(); + if (kids != null) { + for (PDFObject kid : kids) { + if (kid instanceof Placeholder) { + if (((Placeholder) kid).attachKids()) { + validKids.add(kid); + } + } else { + validKids.add(kid); + } + } + } + boolean kidsAttached = !validKids.isEmpty(); + if (kidsAttached) { + PDFArray array = new PDFArray(); + for (PDFObject ob : validKids) { + array.add(ob); + } + put("K", array); + } + return kidsAttached; } + + public static class Placeholder extends PDFStructElem { + + @Override + public void outputInline(OutputStream out, Writer writer) throws IOException { + if (kids != null) { + assert kids.size() > 0; + for (int i = 0; i < kids.size(); i++) { + if (i > 0) { + writer.write(' '); + } + Object obj = kids.get(i); + formatObject(obj, out, writer); + } + } + } + + public Placeholder(PDFObject parent, String name) { + super(parent, new PDFName(name)); + } + } + } diff --git a/src/java/org/apache/fop/render/intermediate/IFContext.java b/src/java/org/apache/fop/render/intermediate/IFContext.java index b8be97253..c59a02ba8 100644 --- a/src/java/org/apache/fop/render/intermediate/IFContext.java +++ b/src/java/org/apache/fop/render/intermediate/IFContext.java @@ -25,6 +25,7 @@ import java.util.Map; import org.apache.xmlgraphics.util.QName; +import org.apache.fop.accessibility.StructureTreeElement; import org.apache.fop.apps.FOUserAgent; /** @@ -46,7 +47,7 @@ public class IFContext { private Locale language; - private String structurePointer; + private StructureTreeElement structureTreeElement; private String id = ""; @@ -132,29 +133,31 @@ public class IFContext { } /** - * Sets the structure pointer for the following painted marks. This method is used when - * accessibility features are enabled. - * @param ptr the structure pointer + * Sets the structure tree element to which the subsequently painted marks + * will correspond. This method is used when accessibility features are + * enabled. + * + * @param structureTreeElement the structure tree element */ - public void setStructurePointer(String ptr) { - this.structurePointer = ptr; + public void setStructureTreeElement(StructureTreeElement structureTreeElement) { + this.structureTreeElement = structureTreeElement; } /** - * Resets the current structure pointer. - * @see #setStructurePointer(String) + * Resets the current structure tree element. + * @see #setStructureTreeElement(String) */ - public void resetStructurePointer() { - setStructurePointer(null); + public void resetStructureTreeElement() { + setStructureTreeElement(null); } /** - * Returns the current structure pointer. - * @return the structure pointer (or null if no pointer is active) - * @see #setStructurePointer(String) + * Returns the current structure tree element. + * @return the structure tree element (or null if no element is active) + * @see #setStructureTreeElement(String) */ - public String getStructurePointer() { - return this.structurePointer; + public StructureTreeElement getStructureTreeElement() { + return this.structureTreeElement; } /** diff --git a/src/java/org/apache/fop/render/intermediate/IFParser.java b/src/java/org/apache/fop/render/intermediate/IFParser.java index 8f0bb88ec..1a384c6e9 100644 --- a/src/java/org/apache/fop/render/intermediate/IFParser.java +++ b/src/java/org/apache/fop/render/intermediate/IFParser.java @@ -49,11 +49,13 @@ import org.apache.commons.logging.LogFactory; import org.apache.xmlgraphics.util.QName; import org.apache.fop.accessibility.AccessibilityEventProducer; +import org.apache.fop.accessibility.StructureTreeElement; import org.apache.fop.accessibility.StructureTreeEventHandler; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fo.ElementMapping; import org.apache.fop.fo.ElementMappingRegistry; import org.apache.fop.fo.expr.PropertyException; +import org.apache.fop.fo.extensions.InternalElementMapping; import org.apache.fop.render.intermediate.extensions.DocumentNavigationExtensionConstants; import org.apache.fop.render.intermediate.extensions.DocumentNavigationHandler; import org.apache.fop.traits.BorderProps; @@ -158,6 +160,9 @@ public class IFParser implements IFConstants { private Attributes pageSequenceAttributes; + private Map structureTreeElements = + new HashMap(); + private final class StructureTreeHandler extends DefaultHandler { private final StructureTreeEventHandler structureTreeEventHandler; @@ -177,7 +182,23 @@ public class IFParser implements IFConstants { public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (!"structure-tree".equals(localName)) { - structureTreeEventHandler.startNode(localName, attributes); + if (localName.equals("marked-content")) { + localName = "#PCDATA"; + } + String structID = attributes.getValue(InternalElementMapping.URI, + InternalElementMapping.STRUCT_ID); + if (structID == null) { + structureTreeEventHandler.startNode(localName, attributes); + } else if (localName.equals("external-graphic") + || localName.equals("instream-foreign-object")) { + StructureTreeElement structureTreeElement = + structureTreeEventHandler.startImageNode(localName, attributes); + structureTreeElements.put(structID, structureTreeElement); + } else { + StructureTreeElement structureTreeElement = + structureTreeEventHandler.startReferencedNode(localName, attributes); + structureTreeElements.put(structID, structureTreeElement); + } } } @@ -225,14 +246,6 @@ public class IFParser implements IFConstants { documentHandler.getContext().resetForeignAttributes(); } - private void establishStructurePointer(String ptr) { - documentHandler.getContext().setStructurePointer(ptr); - } - - private void resetStructurePointer() { - documentHandler.getContext().resetStructurePointer(); - } - /** {@inheritDoc} */ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { @@ -276,7 +289,7 @@ public class IFParser implements IFConstants { } else if (DocumentNavigationExtensionConstants.NAMESPACE.equals(uri)) { if (this.navParser == null) { this.navParser = new DocumentNavigationHandler( - this.documentHandler.getDocumentNavigationHandler()); + this.documentHandler.getDocumentNavigationHandler(), structureTreeElements); } delegate = this.navParser; delegateDepth++; @@ -604,9 +617,9 @@ public class IFParser implements IFConstants { s = lastAttributes.getValue("word-spacing"); int wordSpacing = (s != null ? Integer.parseInt(s) : 0); int[] dx = XMLUtil.getAttributeAsIntArray(lastAttributes, "dx"); - setStructurePointer(lastAttributes); + establishStructureTreeElement(lastAttributes); painter.drawText(x, y, letterSpacing, wordSpacing, dx, content.toString()); - resetStructurePointer(); + resetStructureTreeElement(); } public boolean ignoreCharacters() { @@ -701,7 +714,7 @@ public class IFParser implements IFConstants { int height = Integer.parseInt(lastAttributes.getValue("height")); Map foreignAttributes = getForeignAttributes(lastAttributes); establishForeignAttributes(foreignAttributes); - setStructurePointer(lastAttributes); + establishStructureTreeElement(lastAttributes); if (foreignObject != null) { painter.drawImage(foreignObject, new Rectangle(x, y, width, height)); @@ -715,7 +728,7 @@ public class IFParser implements IFConstants { painter.drawImage(uri, new Rectangle(x, y, width, height)); } resetForeignAttributes(); - resetStructurePointer(); + resetStructureTreeElement(); inForeignObject = false; } @@ -769,13 +782,20 @@ public class IFParser implements IFConstants { return foreignAttributes; } - private void setStructurePointer(Attributes attributes) { - String ptr = attributes.getValue("ptr"); - if (ptr != null && ptr.length() > 0) { - establishStructurePointer(ptr); + private void establishStructureTreeElement(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); } } + private void resetStructureTreeElement() { + documentHandler.getContext().resetStructureTreeElement(); + } + /** {@inheritDoc} */ public void characters(char[] ch, int start, int length) throws SAXException { if (delegate != null) { diff --git a/src/java/org/apache/fop/render/intermediate/IFRenderer.java b/src/java/org/apache/fop/render/intermediate/IFRenderer.java index d217646f6..a2d8a0bea 100644 --- a/src/java/org/apache/fop/render/intermediate/IFRenderer.java +++ b/src/java/org/apache/fop/render/intermediate/IFRenderer.java @@ -50,6 +50,7 @@ import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter; import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema; import org.apache.fop.Version; +import org.apache.fop.accessibility.StructureTreeElement; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.MimeConstants; @@ -629,12 +630,12 @@ public class IFRenderer extends AbstractPathOrientedRenderer { documentHandler.getContext().resetForeignAttributes(); } - private void establishStructurePointer(String ptr) { - documentHandler.getContext().setStructurePointer(ptr); + private void establishStructureTreeElement(StructureTreeElement structureTreeElement) { + documentHandler.getContext().setStructureTreeElement(structureTreeElement); } private void resetStructurePointer() { - documentHandler.getContext().resetStructurePointer(); + documentHandler.getContext().resetStructureTreeElement(); } /** {@inheritDoc} */ @@ -851,8 +852,9 @@ public class IFRenderer extends AbstractPathOrientedRenderer { /** {@inheritDoc} */ public void renderInlineViewport(InlineViewport viewport) { - String ptr = (String) viewport.getTrait(Trait.PTR); - establishStructurePointer(ptr); + StructureTreeElement structElem = + (StructureTreeElement) viewport.getTrait(Trait.STRUCTURE_TREE_ELEMENT); + establishStructureTreeElement(structElem); pushdID(viewport); Dimension dim = new Dimension(viewport.getIPD(), viewport.getBPD()); viewportDimensionStack.push(dim); @@ -912,7 +914,6 @@ public class IFRenderer extends AbstractPathOrientedRenderer { // stuff we only need if a link must be created: Rectangle ipRect = null; AbstractAction action = null; - String ptr = (String) ip.getTrait(Trait.PTR); // used for accessibility // make sure the rect is determined *before* calling super! int ipp = currentIPPosition; int bpp = currentBPPosition + ip.getOffset(); @@ -956,7 +957,9 @@ public class IFRenderer extends AbstractPathOrientedRenderer { // warn if link trait found but not allowed, else create link if (linkTraitFound) { - action.setStructurePointer(ptr); // used for accessibility + StructureTreeElement structElem = + (StructureTreeElement) ip.getTrait(Trait.STRUCTURE_TREE_ELEMENT); + action.setStructureTreeElement(structElem); Link link = new Link(action, ipRect); this.deferredLinks.add(link); } @@ -1009,8 +1012,8 @@ public class IFRenderer extends AbstractPathOrientedRenderer { String fontName = getInternalFontNameForArea(text); int size = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue(); - String ptr = (String)text.getTrait(Trait.PTR); // used for accessibility - establishStructurePointer(ptr); + StructureTreeElement structElem = (StructureTreeElement) text.getTrait(Trait.STRUCTURE_TREE_ELEMENT); + establishStructureTreeElement(structElem); // This assumes that *all* CIDFonts use a /ToUnicode mapping Typeface tf = getTypeface(fontName); diff --git a/src/java/org/apache/fop/render/intermediate/IFSerializer.java b/src/java/org/apache/fop/render/intermediate/IFSerializer.java index a4431b972..c6bf9af9e 100644 --- a/src/java/org/apache/fop/render/intermediate/IFSerializer.java +++ b/src/java/org/apache/fop/render/intermediate/IFSerializer.java @@ -38,9 +38,11 @@ import org.apache.xmlgraphics.util.QName; import org.apache.xmlgraphics.util.XMLizable; import org.apache.fop.accessibility.StructureTreeEventHandler; +import org.apache.fop.fo.extensions.InternalElementMapping; import org.apache.fop.fonts.FontInfo; import org.apache.fop.render.PrintRendererConfigurator; import org.apache.fop.render.RenderingContext; +import org.apache.fop.render.intermediate.IFStructureTreeBuilder.IFStructureTreeElement; import org.apache.fop.render.intermediate.extensions.AbstractAction; import org.apache.fop.render.intermediate.extensions.Bookmark; import org.apache.fop.render.intermediate.extensions.BookmarkTree; @@ -163,6 +165,7 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler handler.startPrefixMapping(XLINK_PREFIX, XLINK_NAMESPACE); handler.startPrefixMapping(DocumentNavigationExtensionConstants.PREFIX, DocumentNavigationExtensionConstants.NAMESPACE); + handler.startPrefixMapping(InternalElementMapping.STANDARD_PREFIX, InternalElementMapping.URI); handler.startElement(EL_DOCUMENT); } catch (SAXException e) { throw new IFException("SAX error in startDocument()", e); @@ -439,7 +442,7 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler addAttribute(atts, "width", Integer.toString(rect.width)); addAttribute(atts, "height", Integer.toString(rect.height)); addForeignAttributes(atts); - addStructurePointerAttribute(atts); + addStructureReference(atts); handler.element(EL_IMAGE, atts); } catch (SAXException e) { throw new IFException("SAX error in startGroup()", e); @@ -467,7 +470,7 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler addAttribute(atts, "width", Integer.toString(rect.width)); addAttribute(atts, "height", Integer.toString(rect.height)); addForeignAttributes(atts); - addStructurePointerAttribute(atts); + addStructureReference(atts); handler.startElement(EL_IMAGE, atts); new DOM2SAX(handler).writeDocument(doc, true); handler.endElement(EL_IMAGE); @@ -582,7 +585,7 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler if (dx != null) { addAttribute(atts, "dx", IFUtil.toString(dx)); } - addStructurePointerAttribute(atts); + addStructureReference(atts); handler.startElement(EL_TEXT, atts); char[] chars = text.toCharArray(); handler.characters(chars, 0, chars.length); @@ -682,13 +685,22 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler XMLUtil.addAttribute(atts, localName, value); } - private void addStructurePointerAttribute(AttributesImpl atts) { - String ptr = getContext().getStructurePointer(); - if (ptr != null) { - addAttribute(atts, "ptr", ptr); + private void addStructureReference(AttributesImpl atts) { + IFStructureTreeElement structureTreeElement = + (IFStructureTreeElement) getContext().getStructureTreeElement(); + if (structureTreeElement != null) { + addStructRefAttribute(atts, structureTreeElement.id); } } + private void addStructRefAttribute(AttributesImpl atts, String id) { + atts.addAttribute(InternalElementMapping.URI, + InternalElementMapping.STRUCT_REF, + InternalElementMapping.STANDARD_PREFIX + ":" + InternalElementMapping.STRUCT_REF, + XMLConstants.CDATA, + id); + } + private void addID() throws SAXException { String id = getContext().getID(); if (!currentID.equals(id)) { @@ -773,7 +785,8 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler atts.addAttribute(null, "rect", "rect", XMLConstants.CDATA, IFUtil.toString(link.getTargetRect())); if (getUserAgent().isAccessibilityEnabled()) { - addAttribute(atts, "ptr", link.getAction().getStructurePointer()); + addStructRefAttribute(atts, + ((IFStructureTreeElement) link.getAction().getStructureTreeElement()).id); } try { handler.startElement(DocumentNavigationExtensionConstants.LINK, atts); diff --git a/src/java/org/apache/fop/render/intermediate/IFStructureTreeBuilder.java b/src/java/org/apache/fop/render/intermediate/IFStructureTreeBuilder.java index 66457681f..b78ae35bc 100644 --- a/src/java/org/apache/fop/render/intermediate/IFStructureTreeBuilder.java +++ b/src/java/org/apache/fop/render/intermediate/IFStructureTreeBuilder.java @@ -26,10 +26,14 @@ import java.util.Locale; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.DefaultHandler; 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.XMLUtil; /** * Saves structure tree events as SAX events in order to replay them when it's @@ -37,42 +41,17 @@ import org.apache.fop.accessibility.StructureTreeEventHandler; */ final class IFStructureTreeBuilder implements StructureTreeEventHandler { - private StructureTreeEventHandler delegate; - - private final List pageSequenceEventRecorders = new ArrayList(); - - /** - * Replay SAX events for a page sequence. - * @param handler The handler that receives SAX events - * @param pageSequenceIndex The index of the page sequence - * @throws SAXException - */ - public void replayEventsForPageSequence(ContentHandler handler, - int pageSequenceIndex) throws SAXException { - pageSequenceEventRecorders.get(pageSequenceIndex).replay(handler); - } - - /** {@inheritDoc} */ - public void startPageSequence(Locale locale) { - SAXEventRecorder eventRecorder = new SAXEventRecorder(); - pageSequenceEventRecorders.add(eventRecorder); - delegate = StructureTree2SAXEventAdapter.newInstance(eventRecorder); - delegate.startPageSequence(locale); - } + static final class IFStructureTreeElement implements StructureTreeElement { - /** {@inheritDoc} */ - public void endPageSequence() { - delegate.endPageSequence(); - } + final String id; - /** {@inheritDoc} */ - public void startNode(String name, Attributes attributes) { - delegate.startNode(name, attributes); - } + IFStructureTreeElement() { + this.id = null; + } - /** {@inheritDoc} */ - public void endNode(String name) { - delegate.endNode(name); + IFStructureTreeElement(String id) { + this.id = id; + } } /** A SAX handler that records events to replay them later. */ @@ -159,22 +138,22 @@ final class IFStructureTreeBuilder implements StructureTreeEventHandler { public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { events.add(new StartElement(uri, localName, qName, attributes)); - }; + } @Override public void endElement(String uri, String localName, String qName) throws SAXException { events.add(new EndElement(uri, localName, qName)); - }; + } @Override public void startPrefixMapping(String prefix, String uri) throws SAXException { events.add(new StartPrefixMapping(prefix, uri)); - }; + } @Override public void endPrefixMapping(String prefix) throws SAXException { events.add(new EndPrefixMapping(prefix)); - }; + } /** * Replays the recorded events. @@ -187,4 +166,69 @@ final class IFStructureTreeBuilder implements StructureTreeEventHandler { } } } + + private StructureTreeEventHandler delegate; + + private final List pageSequenceEventRecorders = new ArrayList(); + + private int idCounter; + + /** + * Replay SAX events for a page sequence. + * @param handler The handler that receives SAX events + * @param pageSequenceIndex The index of the page sequence + * @throws SAXException + */ + public void replayEventsForPageSequence(ContentHandler handler, + int pageSequenceIndex) throws SAXException { + pageSequenceEventRecorders.get(pageSequenceIndex).replay(handler); + } + + public void startPageSequence(Locale locale) { + SAXEventRecorder eventRecorder = new SAXEventRecorder(); + pageSequenceEventRecorders.add(eventRecorder); + delegate = StructureTree2SAXEventAdapter.newInstance(eventRecorder); + delegate.startPageSequence(locale); + } + + public void endPageSequence() { + delegate.endPageSequence(); + } + + public StructureTreeElement startNode(String name, Attributes attributes) { + delegate.startNode(name, attributes); + return new IFStructureTreeElement(); + } + + public void endNode(String name) { + delegate.endNode(name); + } + + public StructureTreeElement startImageNode(String name, Attributes attributes) { + String id = getNextID(); + AttributesImpl atts = addIDAttribute(attributes, id); + delegate.startImageNode(name, atts); + return new IFStructureTreeElement(id); + } + + public StructureTreeElement startReferencedNode(String name, Attributes attributes) { + String id = getNextID(); + AttributesImpl atts = addIDAttribute(attributes, id); + delegate.startReferencedNode(name, atts); + return new IFStructureTreeElement(id); + } + + private String getNextID() { + return Integer.toHexString(idCounter++); + } + + private AttributesImpl addIDAttribute(Attributes attributes, String id) { + AttributesImpl atts = new AttributesImpl(attributes); + atts.addAttribute(InternalElementMapping.URI, + InternalElementMapping.STRUCT_ID, + InternalElementMapping.STANDARD_PREFIX + ":" + InternalElementMapping.STRUCT_ID, + XMLUtil.CDATA, + id); + return atts; + } } diff --git a/src/java/org/apache/fop/render/intermediate/extensions/AbstractAction.java b/src/java/org/apache/fop/render/intermediate/extensions/AbstractAction.java index 340b2e068..a2595d320 100644 --- a/src/java/org/apache/fop/render/intermediate/extensions/AbstractAction.java +++ b/src/java/org/apache/fop/render/intermediate/extensions/AbstractAction.java @@ -21,13 +21,15 @@ package org.apache.fop.render.intermediate.extensions; import org.apache.xmlgraphics.util.XMLizable; +import org.apache.fop.accessibility.StructureTreeElement; + /** * Abstract base class for document actions, like "go-to" actions with absolute page coordinates. */ public abstract class AbstractAction implements XMLizable { private String id; - private String structurePointer; + private StructureTreeElement structureTreeElement; /** * Sets an ID to make the action referencable. @@ -47,18 +49,18 @@ public abstract class AbstractAction implements XMLizable { /** * Sets the structure element corresponding to this action. - * @param structurePointer a reference to the structure element + * @param structureTreeElement a reference to the structure element */ - public void setStructurePointer(String structurePointer) { - this.structurePointer = structurePointer; + public void setStructureTreeElement(StructureTreeElement structureTreeElement) { + this.structureTreeElement = structureTreeElement; } /** * Returns the structure element corresponding to this action. * @return the reference to the structure element */ - public String getStructurePointer() { - return structurePointer; + public StructureTreeElement getStructureTreeElement() { + return structureTreeElement; } /** diff --git a/src/java/org/apache/fop/render/intermediate/extensions/DocumentNavigationHandler.java b/src/java/org/apache/fop/render/intermediate/extensions/DocumentNavigationHandler.java index 1e613d7eb..693497b73 100644 --- a/src/java/org/apache/fop/render/intermediate/extensions/DocumentNavigationHandler.java +++ b/src/java/org/apache/fop/render/intermediate/extensions/DocumentNavigationHandler.java @@ -21,6 +21,7 @@ package org.apache.fop.render.intermediate.extensions; import java.awt.Point; import java.awt.Rectangle; +import java.util.Map; import java.util.Stack; import org.xml.sax.Attributes; @@ -30,6 +31,8 @@ import org.xml.sax.helpers.DefaultHandler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.fop.accessibility.StructureTreeElement; +import org.apache.fop.fo.extensions.InternalElementMapping; import org.apache.fop.render.intermediate.IFDocumentNavigationHandler; import org.apache.fop.render.intermediate.IFException; import org.apache.fop.util.XMLUtil; @@ -48,14 +51,20 @@ public class DocumentNavigationHandler extends DefaultHandler private IFDocumentNavigationHandler navHandler; - private String structurePointer; + private StructureTreeElement structureTreeElement; + + private Map structureTreeElements; /** * Main constructor. * @param navHandler the navigation handler that will receive the events + * @param structureTreeElements the elements representing the structure of the document */ - public DocumentNavigationHandler(IFDocumentNavigationHandler navHandler) { + public DocumentNavigationHandler(IFDocumentNavigationHandler navHandler, + Map structureTreeElements) { this.navHandler = navHandler; + assert structureTreeElements != null; + this.structureTreeElements = structureTreeElements; } /** {@inheritDoc} */ @@ -98,7 +107,8 @@ public class DocumentNavigationHandler extends DefaultHandler throw new SAXException(localName + " must be the root element!"); } Rectangle targetRect = XMLUtil.getAttributeAsRectangle(attributes, "rect"); - structurePointer = attributes.getValue("ptr"); + structureTreeElement = structureTreeElements.get( + attributes.getValue(InternalElementMapping.URI, InternalElementMapping.STRUCT_REF)); Link link = new Link(null, targetRect); objectStack.push(link); } else if (GOTO_XY.getLocalName().equals(localName)) { @@ -121,8 +131,8 @@ public class DocumentNavigationHandler extends DefaultHandler } action = new GoToXYAction(id, pageIndex, location); } - if (structurePointer != null) { - action.setStructurePointer(structurePointer); + if (structureTreeElement != null) { + action.setStructureTreeElement(structureTreeElement); } objectStack.push(action); } else if (GOTO_URI.getLocalName().equals(localName)) { @@ -134,8 +144,8 @@ public class DocumentNavigationHandler extends DefaultHandler if (id != null) { action.setID(id); } - if (structurePointer != null) { - action.setStructurePointer(structurePointer); + if (structureTreeElement != null) { + action.setStructureTreeElement(structureTreeElement); } objectStack.push(action); } else { diff --git a/src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java b/src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java index c8fa481d4..2236778b5 100644 --- a/src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java +++ b/src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java @@ -31,6 +31,7 @@ import org.apache.fop.pdf.PDFFactory; import org.apache.fop.pdf.PDFGoTo; import org.apache.fop.pdf.PDFLink; import org.apache.fop.pdf.PDFOutline; +import org.apache.fop.pdf.PDFStructElem; import org.apache.fop.render.intermediate.IFDocumentNavigationHandler; import org.apache.fop.render.intermediate.IFException; import org.apache.fop.render.intermediate.extensions.AbstractAction; @@ -111,10 +112,9 @@ public class PDFDocumentNavigationHandler implements IFDocumentNavigationHandler PDFLink pdfLink = getPDFDoc().getFactory().makeLink( targetRect2D, pdfAction); if (pdfLink != null) { - String ptr = link.getAction().getStructurePointer(); - if (documentHandler.getUserAgent().isAccessibilityEnabled() - && ptr != null && ptr.length() > 0) { - documentHandler.getLogicalStructureHandler().addLinkContentItem(pdfLink, ptr); + PDFStructElem structure = (PDFStructElem) link.getAction().getStructureTreeElement(); + if (documentHandler.getUserAgent().isAccessibilityEnabled() && structure != null) { + documentHandler.getLogicalStructureHandler().addLinkContentItem(pdfLink, structure); } documentHandler.currentPage.addAnnotation(pdfLink); } diff --git a/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java b/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java index d49ef4a3e..88a6e9c22 100644 --- a/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java +++ b/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java @@ -19,9 +19,7 @@ package org.apache.fop.render.pdf; -import java.util.HashMap; import java.util.Locale; -import java.util.Map; import org.apache.fop.pdf.PDFArray; import org.apache.fop.pdf.PDFDictionary; @@ -47,11 +45,6 @@ class PDFLogicalStructureHandler { private final PDFDocument pdfDoc; - /** - * Map of references to the corresponding structure elements. - */ - private final Map structTreeMap = new HashMap(); - private final PDFParentTree parentTree = new PDFParentTree(); private int parentTreeKey; @@ -151,100 +144,79 @@ class PDFLogicalStructureHandler { parentTree.getNums().put(currentPage.getStructParents(), pageParentTreeArray); } - private MarkedContentInfo addToParentTree(String structurePointer) { - PDFStructElem parent = (PDFStructElem) structTreeMap.get(structurePointer); - if (parent == null) { - return ARTIFACT; - } else { - pageParentTreeArray.add(parent); - String type = parent.getStructureType().toString(); - int mcid = pageParentTreeArray.length() - 1; - return new MarkedContentInfo(type, mcid, parent); - } + private MarkedContentInfo addToParentTree(PDFStructElem structureTreeElement) { + PDFStructElem parent = (structureTreeElement instanceof PDFStructElem.Placeholder) + ? structureTreeElement.getParentStructElem() + : structureTreeElement; + pageParentTreeArray.add(parent); + String type = parent.getStructureType().toString(); + int mcid = pageParentTreeArray.length() - 1; + return new MarkedContentInfo(type, mcid, structureTreeElement); } /** * Adds a content item corresponding to text into the structure tree, if * there is a structure element associated to it. * - * @param structurePointer reference to the parent structure element of the - * piece of text + * @param structElem the parent structure element of the piece of text * @return the necessary information for bracketing the content as a * marked-content sequence. If there is no element in the structure tree * associated to that content, returns an instance whose * {@link MarkedContentInfo#tag} value is null. The content * must then be treated as an artifact. */ - MarkedContentInfo addTextContentItem(String structurePointer) { - MarkedContentInfo mci = addToParentTree(structurePointer); - if (mci != ARTIFACT) { + MarkedContentInfo addTextContentItem(PDFStructElem structElem) { + if (structElem == null) { + return ARTIFACT; + } else { + MarkedContentInfo mci = addToParentTree(structElem); PDFDictionary contentItem = new PDFDictionary(); contentItem.put("Type", MCR); contentItem.put("Pg", this.currentPage); contentItem.put("MCID", mci.mcid); mci.parent.addKid(contentItem); + return mci; } - return mci; } /** * Adds a content item corresponding to an image into the structure tree, if * there is a structure element associated to it. * - * @param structurePointer reference to the parent structure element of the - * image + * @param structElem the parent structure element of the image * @return the necessary information for bracketing the content as a * marked-content sequence. If there is no element in the structure tree * associated to that image, returns an instance whose - * {@link MarkedContentInfo#tag} value is null. The image - * must then be treated as an artifact. + * {@link MarkedContentInfo#tag} value is null. The image must + * then be treated as an artifact. */ - MarkedContentInfo addImageContentItem(String structurePointer) { - MarkedContentInfo mci = addToParentTree(structurePointer); - if (mci != ARTIFACT) { + MarkedContentInfo addImageContentItem(PDFStructElem structElem) { + if (structElem == null) { + return ARTIFACT; + } else { + MarkedContentInfo mci = addToParentTree(structElem); mci.parent.setMCIDKid(mci.mcid); mci.parent.setPage(this.currentPage); + return mci; } - return mci; } - // While the PDF spec allows images to be referred as PDF objects, this - // makes the Acrobat Pro checker complain that the image is not accessible. - // Its alt-text is still read aloud though. Using marked-content sequences - // like for text works. -// MarkedContentInfo addImageObject(String parentReference) { -// MarkedContentInfo mci = addToParentTree(parentReference); -// if (mci != ARTIFACT) { -// PDFDictionary contentItem = new PDFDictionary(); -// contentItem.put("Type", OBJR); -// contentItem.put("Pg", this.currentPage); -// contentItem.put("Obj", null); -// mci.parent.addKid(contentItem); -// } -// return mci; -// } - /** * Adds a content item corresponding to the given link into the structure * tree. * * @param link a link - * @param structurePointer reference to the corresponding parent structure element + * @param structureTreeElement its parent structure element */ - void addLinkContentItem(PDFLink link, String structurePointer) { + void addLinkContentItem(PDFLink link, PDFStructElem structureTreeElement) { int structParent = getNextParentTreeKey(); link.setStructParent(structParent); PDFDictionary contentItem = new PDFDictionary(); contentItem.put("Type", OBJR); contentItem.put("Pg", this.currentPage); contentItem.put("Obj", link); - PDFStructElem parent = (PDFStructElem) structTreeMap.get(structurePointer); - parentTree.getNums().put(structParent, parent); - parent.addKid(contentItem); - } - - void addStructurePointer(String ptr, PDFStructElem structElem) { - structTreeMap.put(ptr, structElem); + parentTree.getNums().put(structParent, structureTreeElement); + structureTreeElement.addKid(contentItem); } } diff --git a/src/java/org/apache/fop/render/pdf/PDFPainter.java b/src/java/org/apache/fop/render/pdf/PDFPainter.java index 11af216a2..f2fbfd014 100644 --- a/src/java/org/apache/fop/render/pdf/PDFPainter.java +++ b/src/java/org/apache/fop/render/pdf/PDFPainter.java @@ -37,6 +37,7 @@ import org.apache.fop.fonts.SingleByteFont; import org.apache.fop.fonts.Typeface; import org.apache.fop.pdf.PDFDocument; import org.apache.fop.pdf.PDFNumber; +import org.apache.fop.pdf.PDFStructElem; import org.apache.fop.pdf.PDFTextUtil; import org.apache.fop.pdf.PDFXObject; import org.apache.fop.render.RenderingContext; @@ -133,24 +134,24 @@ public class PDFPainter extends AbstractIFPainter { PDFXObject xobject = getPDFDoc().getXObject(uri); if (xobject != null) { if (accessEnabled) { - String ptr = getContext().getStructurePointer(); - prepareImageMCID(ptr); + PDFStructElem structElem = (PDFStructElem) getContext().getStructureTreeElement(); + prepareImageMCID(structElem); placeImageAccess(rect, xobject); } else { placeImage(rect, xobject); } } else { if (accessEnabled) { - String ptr = getContext().getStructurePointer(); - prepareImageMCID(ptr); + PDFStructElem structElem = (PDFStructElem) getContext().getStructureTreeElement(); + prepareImageMCID(structElem); } drawImageUsingURI(uri, rect); flushPDFDoc(); } } - private void prepareImageMCID(String ptr) { - imageMCI = logicalStructureHandler.addImageContentItem(ptr); + private void prepareImageMCID(PDFStructElem structElem) { + imageMCI = logicalStructureHandler.addImageContentItem(structElem); } /** {@inheritDoc} */ @@ -194,8 +195,8 @@ public class PDFPainter extends AbstractIFPainter { /** {@inheritDoc} */ public void drawImage(Document doc, Rectangle rect) throws IFException { if (accessEnabled) { - String ptr = getContext().getStructurePointer(); - prepareImageMCID(ptr); + PDFStructElem structElem = (PDFStructElem) getContext().getStructureTreeElement(); + prepareImageMCID(structElem); } drawImageUsingDocument(doc, rect); flushPDFDoc(); @@ -294,8 +295,8 @@ public class PDFPainter extends AbstractIFPainter { String text) throws IFException { if (accessEnabled) { - String ptr = getContext().getStructurePointer(); - MarkedContentInfo mci = logicalStructureHandler.addTextContentItem(ptr); + PDFStructElem structElem = (PDFStructElem) getContext().getStructureTreeElement(); + MarkedContentInfo mci = logicalStructureHandler.addTextContentItem(structElem); if (generator.getTextUtil().isInTextObject()) { generator.separateTextElements(mci.tag, mci.mcid); } diff --git a/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java b/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java index 8ec10b209..3b5b00c33 100644 --- a/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java +++ b/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java @@ -24,10 +24,10 @@ import java.util.Locale; import org.xml.sax.Attributes; +import org.apache.fop.accessibility.StructureTreeElement; import org.apache.fop.accessibility.StructureTreeEventHandler; import org.apache.fop.events.EventBroadcaster; import org.apache.fop.fo.extensions.ExtensionElementMapping; -import org.apache.fop.fo.extensions.InternalElementMapping; import org.apache.fop.pdf.PDFFactory; import org.apache.fop.pdf.PDFStructElem; @@ -61,33 +61,64 @@ class PDFStructureTreeBuilder implements StructureTreeEventHandler { public void endPageSequence() { } - public void startNode(String name, Attributes attributes) { + public StructureTreeElement startNode(String name, Attributes attributes) { PDFStructElem parent = ancestors.getFirst(); String role = attributes.getValue("role"); - PDFStructElem created = pdfFactory.makeStructureElement( - FOToPDFRoleMap.mapFormattingObject(name, role, parent, - eventBroadcaster), parent); - if (ancestors.size() <= 2) { // TODO remove - parent.addKid(created); - } - String ptr = attributes.getValue(InternalElementMapping.URI, "ptr"); - if (ptr != null) { - logicalStructureHandler.addStructurePointer(ptr, created); + PDFStructElem created; + created = pdfFactory.makeStructureElement( + FOToPDFRoleMap.mapFormattingObject(name, role, parent, eventBroadcaster), parent); + parent.addKid(created); + ancestors.addFirst(created); + return created; + } + + public void endNode(String name) { + removeFirstAncestor(); + } + + private void removeFirstAncestor() { + ancestors.removeFirst(); + } + + public StructureTreeElement startImageNode(String name, Attributes attributes) { + PDFStructElem parent = ancestors.getFirst(); + String role = attributes.getValue("role"); + PDFStructElem created; + created = pdfFactory.makeStructureElement( + FOToPDFRoleMap.mapFormattingObject(name, role, parent, eventBroadcaster), parent); + parent.addKid(created); + String altTextNode = attributes.getValue(ExtensionElementMapping.URI, "alt-text"); + if (altTextNode != null) { + created.put("Alt", altTextNode); + } else { + created.put("Alt", "No alternate text specified"); } + ancestors.addFirst(created); + return created; + } + + public void endImageNode(String name) { + removeFirstAncestor(); + } - if (name.equals("external-graphic") || name.equals("instream-foreign-object")) { - String altTextNode = attributes.getValue(ExtensionElementMapping.URI, "alt-text"); - if (altTextNode != null) { - created.put("Alt", altTextNode); - } else { - created.put("Alt", "No alternate text specified"); - } + public StructureTreeElement startReferencedNode(String name, Attributes attributes) { + PDFStructElem parent = ancestors.getFirst(); + String role = attributes.getValue("role"); + PDFStructElem created; + if ("#PCDATA".equals(name)) { + created = new PDFStructElem.Placeholder(parent, name); + } else { + created = pdfFactory.makeStructureElement( + FOToPDFRoleMap.mapFormattingObject(name, role, parent, + eventBroadcaster), parent); } + parent.addKid(created); ancestors.addFirst(created); + return created; } - public void endNode(String name) { - ancestors.removeFirst(); + public void endReferencedNode(String name) { + removeFirstAncestor(); } } diff --git a/src/java/org/apache/fop/render/rtf/RTFHandler.java b/src/java/org/apache/fop/render/rtf/RTFHandler.java index 8878b5d24..a3e3db461 100644 --- a/src/java/org/apache/fop/render/rtf/RTFHandler.java +++ b/src/java/org/apache/fop/render/rtf/RTFHandler.java @@ -117,13 +117,13 @@ import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfFootnote; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfHyperLink; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfList; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListItem; +import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListItem.RtfListItemLabel; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfPage; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTable; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableCell; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow; import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTextrun; -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListItem.RtfListItemLabel; import org.apache.fop.render.rtf.rtflib.tools.BuilderContext; import org.apache.fop.render.rtf.rtflib.tools.PercentContext; import org.apache.fop.render.rtf.rtflib.tools.TableContext; @@ -1362,11 +1362,9 @@ public class RTFHandler extends FOEventHandler { /** * @param text FOText object - * @param data Array of characters to process. - * @param start Offset for characters to process. - * @param length Portion of array to process. + * @param characters CharSequence of the characters to process. */ - public void text(FOText text, char[] data, int start, int length) { + public void text(FOText text, CharSequence characters) { if (bDefer) { return; } @@ -1381,7 +1379,7 @@ public class RTFHandler extends FOEventHandler { = TextAttributesConverter.convertCharacterAttributes(text); textrun.pushInlineAttributes(rtfAttr); - textrun.addString(new String(data, start, length - start)); + textrun.addString(characters.toString()); textrun.popInlineAttributes(); } catch (IOException ioe) { handleIOTrouble(ioe); @@ -1558,7 +1556,7 @@ public class RTFHandler extends FOEventHandler { } else if (foNode instanceof FOText) { if (bStart) { FOText text = (FOText) foNode; - text(text, text.getCharArray(), 0, text.length()); + text(text, text.getCharSequence()); } } else if (foNode instanceof Character) { if (bStart) { diff --git a/test/accessibility/background-image_jpg_repeat.fo b/test/accessibility/background-image_jpg_repeat.fo index 2c8f7f66d..727162e49 100644 --- a/test/accessibility/background-image_jpg_repeat.fo +++ b/test/accessibility/background-image_jpg_repeat.fo @@ -16,14 +16,14 @@ limitations under the License. --> - + - + Apache FOP (Formatting Objects Processor) is a print formatter driven by XSL formatting objects (XSL-FO) and an output independent formatter. It is a Java application diff --git a/test/accessibility/background-image_jpg_single.fo b/test/accessibility/background-image_jpg_single.fo index 2250c24e2..335353e03 100644 --- a/test/accessibility/background-image_jpg_single.fo +++ b/test/accessibility/background-image_jpg_single.fo @@ -16,7 +16,7 @@ limitations under the License. --> - + @@ -25,7 +25,7 @@ background-position-vertical="50%"/> - + Apache FOP (Formatting Objects Processor) is a print formatter driven by XSL formatting objects (XSL-FO) and an output independent formatter. It is a Java application diff --git a/test/accessibility/background-image_png_repeat.fo b/test/accessibility/background-image_png_repeat.fo index 7506c0f2b..5e4a8ba0d 100644 --- a/test/accessibility/background-image_png_repeat.fo +++ b/test/accessibility/background-image_png_repeat.fo @@ -16,14 +16,14 @@ limitations under the License. --> - + - + Apache FOP (Formatting Objects Processor) is a print formatter driven by XSL formatting objects (XSL-FO) and an output independent formatter. It is a Java application diff --git a/test/accessibility/background-image_png_single.fo b/test/accessibility/background-image_png_single.fo index 1f60e9411..90067ec53 100644 --- a/test/accessibility/background-image_png_single.fo +++ b/test/accessibility/background-image_png_single.fo @@ -16,7 +16,7 @@ limitations under the License. --> - + @@ -25,7 +25,7 @@ background-position-vertical="50%"/> - + Apache FOP (Formatting Objects Processor) is a print formatter driven by XSL formatting objects (XSL-FO) and an output independent formatter. It is a Java application diff --git a/test/accessibility/background-image_svg_repeat.fo b/test/accessibility/background-image_svg_repeat.fo index 6e71409d0..02520b6cf 100644 --- a/test/accessibility/background-image_svg_repeat.fo +++ b/test/accessibility/background-image_svg_repeat.fo @@ -16,14 +16,14 @@ limitations under the License. --> - + - + Apache FOP (Formatting Objects Processor) is a print formatter driven by XSL formatting objects (XSL-FO) and an output independent formatter. It is a Java application diff --git a/test/accessibility/background-image_svg_single.fo b/test/accessibility/background-image_svg_single.fo index 9dc67c86c..3029f32ec 100644 --- a/test/accessibility/background-image_svg_single.fo +++ b/test/accessibility/background-image_svg_single.fo @@ -16,7 +16,7 @@ limitations under the License. --> - + @@ -25,7 +25,7 @@ background-position-vertical="50%"/> - + Apache FOP (Formatting Objects Processor) is a print formatter driven by XSL formatting objects (XSL-FO) and an output independent formatter. It is a Java application diff --git a/test/accessibility/complete.fo b/test/accessibility/complete.fo index 81df372b5..75684750c 100644 --- a/test/accessibility/complete.fo +++ b/test/accessibility/complete.fo @@ -17,7 +17,7 @@ --> + xmlns:fox="http://xmlgraphics.apache.org/fop/extensions" language="en" country="GB"> @@ -25,7 +25,7 @@ - + This is the page headerPage @@ -117,7 +117,7 @@ And now we are going to see how a second page sequence is handled. - + This is the page headerPage diff --git a/test/accessibility/image_jpg.fo b/test/accessibility/image_jpg.fo index be0e24bee..5fe36f61a 100644 --- a/test/accessibility/image_jpg.fo +++ b/test/accessibility/image_jpg.fo @@ -17,14 +17,14 @@ --> + xmlns:fox="http://xmlgraphics.apache.org/fop/extensions" language="en" country="GB"> - + This document contains an image in the JPEG format: + xmlns:fox="http://xmlgraphics.apache.org/fop/extensions" language="en" country="GB"> - + This document contains an image in the PNG format: + xmlns:fox="http://xmlgraphics.apache.org/fop/extensions" language="en" country="GB"> - + This document contains an image in the SVG format: + xmlns:fox="http://xmlgraphics.apache.org/fop/extensions" language="en" country="GB"> - + This document contains an image in the WMF format: - + - + This is a text followed by a leader with leader-pattern=​"use-content", the diff --git a/test/accessibility/links.fo b/test/accessibility/links.fo index 66f0f66f4..36250e332 100644 --- a/test/accessibility/links.fo +++ b/test/accessibility/links.fo @@ -17,14 +17,14 @@ --> + xmlns:fox="http://xmlgraphics.apache.org/fop/extensions" language="en" country="GB"> - + This is a link to the next diff --git a/test/accessibility/pdf/background-image_jpg_repeat.pdf b/test/accessibility/pdf/background-image_jpg_repeat.pdf index 97b304c5396c53a5d3cd3ceaa98b451c2288f94b..22176175755ca4b25849b3172b88e14b16a0ff4a 100644 GIT binary patch delta 544 zcmeB6X-k<<&uwI2Xk>0^Xkch;y0Pm6FKcR^uDjFZW#BhWUG|P3k4)6ujdz=%+3E#0A0;wNr4Ou!Oar|ehD)gZSGNtWuN>;muvHP?Q6_h zMrH~IAfS+^zy)R)8X8)dVu%@=8czPM?-yiXfgxpPfT`Tf0@GM?3j++j7N(YyryHo( zW0+uMXkvn<+Q7uv1lo delta 540 zcmaivy-EX75QPaA;uXV!*l%GF42v^&?%#y4#o}(MAhtn-C_-R`7%|;;B7z#YPa^vy z*1myFtgVa+3VQ=iHGFes&Y9cc<8W53BcfDj0f?XP-#6B#$#pp@FKi-_0V0T`=Haf|F2{q(o|ecPREn!`0QMuL}tHq)$ diff --git a/test/accessibility/pdf/background-image_jpg_single.pdf b/test/accessibility/pdf/background-image_jpg_single.pdf index e1d7f93406611a7cf77e0de44b55acbc22dbf205..232afdd05757996aa98798b4eeef2f8e360d539b 100644 GIT binary patch delta 528 zcmaEx^fYNgJ-3m8p^>?vp@E^X*~YF9ysW8ty6#SsoB5o?jdTqRb&bqJ3=ORe46TgK zqHOe2lC4rEFBFiRyq;fdGB^J}0dzH!B?U4t1UF9<_$AC}w7ExR58GsKU9Qbx+Si#i zO%)74Kp{_o3(Nqz!N>$d%+S(ca+tnfkcl~ll!*zZa#JHrW6caLG4z^QT1@_?uU?O7 zf~AEqnrZ_RV-o{(F-v0%Qw=P!sx!l)*TN8Do*CTt29`iu&@3@DurS8(wtx3HiVQ+4m1?uFyK;Eb@g}S F0s#6Zb(;VH delta 539 zcmaivKT88a5XA|C;ELfu?5{A0gd;P%vwtRp19MryCW6?C7*GV^gcvd1wIT?C`y_I$ zpTN#Ot)*gZC5kBA2Apd6&6}C`UPiB@S+RWr1Fe*#{pGYfXzPa5-^9+*^M1{~GR zAUGq-C+Hn(J7DFk<4g{`&Ln!NvmMXm`{dZ$H17Q?ITC3qt|lkr$#i^rCQyQMqSf;I GyW$gwKYD@y diff --git a/test/accessibility/pdf/background-image_png_repeat.pdf b/test/accessibility/pdf/background-image_png_repeat.pdf index 9f5e7ff124e8149f2b6381b8cec0b4fbac3f8859..52da4020ac95276d873a9b2ab6ed09b99bc65d83 100644 GIT binary patch delta 533 zcmaivze>YU6o;`QVv05(DBZGT5rXGm?!5^?XhP!PPzut))e3^pClER)QadTPFVH6t z$qV=l4!(h-;M7sHPLex#ro(r>^W&V4dFy@NdYH5ckTfD7>*v|$_Qu6HI?nCQPQFhO zU_|;9F$GLnpJj)m^K@hve%C&A_H4WJc8+I7&f~0v?CX72sJtpzq|CKaCax&%l|Tjjkc6rpl}ADLpJE5I N-7OR^49kAyeFL@ddA9} zaDTws&f3~iv9i|KD7S@E4c|QGy_wfV^KH?5C^r#NGg<(~<=w~D#x%YvM#aT-;mTGo zz!)*se2BIU&}OWjTio!d+YZh>SltJoqlT$wH;?PTTdTd<%i2ytA*?DaLiN)S32Kj} zqTT*{c#zg7tjTzc(0Ys!eU^fIpGPHw=g8J3H9asf*BGI&=Y?X#*NM+kgq2SIo{y>V zUt)AU43S~uo^CtG&?iR9$?|uUyer87`aKJxO_w$9N)~qhl^m%oQ=Rg9 zh#ce%G?kT@PDFhHpFl)y?A>Ivw_pm?CW?YqxE;WM6ggfV2Pr delta 542 zcmaivu}T9$5QYf{f-8n=?5~MM;9zEUcJ?-egPie7gJ3ISp$NhWF=D#w1wpu{uo2{* z!K4zg&_*oO7w{28EtFfqsfKUWsMWntOBjU(o ziBNU*GTL;_iA5BjIqNZU=rL`f+IU?p6VK3!F%3DeW^ORUPP|=qi5JQM{K4qk!~RNd zz$Q%-G0=R*h#{%EZ~Ywr0?CJVjSw3DBn N8Eb)5r?WoF)d#QhetZA` diff --git a/test/accessibility/pdf/background-image_svg_repeat.pdf b/test/accessibility/pdf/background-image_svg_repeat.pdf index 0e438958dcd21a35f596ef38bad50fb75a2d0314..0bce2404de1579bc9ebc4e1f33de9f986a069060 100644 GIT binary patch delta 767 zcmaixy-EW?5XT8B!ih;Fpu}pyFCqkI=63gP;~MjEiIs>Sl^`M-u@DQj5E~J(u@GgR zz|Kx2jise!d<5S>UqC!X1aAeGDRyW6^JC{fo%7VwdFtwFDv4v^9qN2drFtGSuvPe3Z;QuQBHZ495r1ajD+;~U6OCH(?v5c#>9TXg1A@VUuf z+W-ZwYcU~7MQMD)s%F=ljYecBQi1PlMTV-XS=SNidNa}(g;819ePx$GSrZtNc( R?YFi))D)sOHr7~ZdLO1js$Kv9 delta 823 zcmah{v1%JZ5JhoPWE~3`p~eu{#*T#%nHkN_-AadSNl2-TAW0jHf^9+!Cy;IIPL+xT z0)hRKa9@xvrTrP{5`TgBQrOb1Aj1~BZ-#mA&CaiR>1JN~K3hjbVvGP-etiA2@%*}R znVzMStJKZPy$UuE8^rH1Y5}xZvfDD30@T$ip8_!ZR@o`7i#kbw0`~O9UAS=!;@m|&*Rf*TFkO0e$1k1 zlq^eLtUWQ{e(qOmRzn^-)#~2`4Mo=d-ap(EkRTU9GsI$cTdf!8gKYD~SnA+0Zn{POdX1hS!Vm(#pg9fy|Bv4=ADy?(-7HIh6e0pLJ>PzAt`COZVPdXx$u@a_ z9)-t~;` lNr&PSq)Drx;(w7-r_pf6lk?GJIvQL$;sZLBO6#cYd;{>WeaHX+ delta 539 zcmaivu}Z{15QYg>u6RVkbrySIA{N1!-PzsbI0G>zR;O^$_h?3eE-kK%xnL>|1eoVL_uf($UNPBEY6SPtNOgYxUTJ_wdrGw z7z^4*(*@{~X{Igm9BSMCnFE`9Kk_`?JTJYpepqk#TVOaE4t&5kU*FzC#Zfg!o#nYT z#o=ps&Dr+?iO}RQl4KuOb_PN_krC2i3Al1p9V#)Rk_v#X4iG1z)P%(dWS{6mFKb)mDYKIxvErIloGWn2@Hrl+`g8V^rSSt=oAVOZ`~>=T|1dQt!Y diff --git a/test/accessibility/pdf/complete.pdf b/test/accessibility/pdf/complete.pdf index a42bb2a976b5bb429ba0e1fae3e4628b39f1d1d1..cffb9e2cb52bb8d2239d079e70f6bfcccae155b4 100644 GIT binary patch delta 3350 zcmai1&ud*(5auG;++chnB9#_ik!&h~Gjqq)9f|dhp8PV||EuAX zC;z>;4m;8MZx%R$jmU#6`!zjCBBs1keuTKfJ{1%(TzIs5E*FY#6T;j6%I4#NVz0nm9;99^RH}3VGN)J zzZw8wWCB{FU#?3RqXJtoS?b`R6ug`jGD)0(>XfAJ98DzvgUNex9=E$_Q%#D3bAV7g z2^oS2CD4p;ya+PJ5KnnI;V!786%M5Ut&&k6QW9h*Dj3)zFqngP$jW8c?IaaqI9|B5llCql1@HMGcBZ$UEz$jh+-{C;G7SdI=N1LGE_AQs(gv?0-#20 zCm-#g1r>rO!^a}QtnlZ8&dS;U`dzc}0kR(bSF!GuO|?yu!SHmO z_Se5}Ug;Kzp3S*jWO%F%zp>~dfotiDDb-RH@oK_dhIB>JJnq8VN<^R$^PtSiVfG-k z%yaN}PkqiYgH6)%G#a#(3(iJ=;J|9i;_IajQk=@lR-#1+TpTu@3te5UToh!U{pnZ- z_N7*81(sq0U=mr~uf>%=2b0Gd7abp53pNIQ6o2ESe*4Gf?a$LKp@V%(yE{rd@z&m+ t&`#bzIB?sZccE-g-}>Jpv;Qg{JpAJR!yoP+-D@rS1Et;E+<)(&{SU||m_7gi delta 3289 zcmai1PmA0|5T%t798Gq?KS>~my+lM@?5ggnu3F;ixb7kzHbTN4M3Imv0m&|jF-9*x z@aSn_4!@&*01+gId;>p#ha5bp;1>|~;4Rv-JG(p6Z@@VXHPu~JuimTb`SoD%+rePJ zdya@WQ;9L#&)*%KdG^8Tm%E?u?tQg8{`TxU=V+B^mGdB7$5F0Z~hYW;p4|IeRLY*(cc`dJl%h=9+vti8lLa}+6m|T zw=}%o@4Xk6`+qeI`X4o%>-XQUF5C5o0S(vJhmVFOT))`AeeLMrGfx%j|JVr^`|oc} z{H~t({eCrUUwAFiN}POFc2|anUy2DQu&GPGb31Ims@neM5$|y7|GXVu?6`n;ig<%& z^fQ4h+!Mon?$X#SQi_MR?zAk6DLFW1LYr8dpheXTXG^ixM#q7tal4AB5mQ^8QA&_C zWkQ=+Td|QU+H6|!Ou^)-zq1!!=oso@ijWeM!?n!i2*{ahIWu6!vfw_QQf0OYTm*n* z!^W^9W+_7VEfGP2iFppk!zQG(z%dzgFi8Xyk{AY2he9$7Af2=J;ZAKr1kiHvmf@BS zNtIooSrzYAwerpjSF?x^8evO}F+oeHpE|FB z3#M`2R`EA0n6=r0z@9)C9$_h%Qxl}da3;`zv*)fIm7Y-%o*kI(3nrke0zbSI;D?{? zknVWBnY*^td5o}Zye^S>2xF`uBvR?uS=8flO1%t*y2Y9wm}pTY^>_%m)!fQj1Ip+W&JuoavxC zaf6nK5Ijai_;{$C%oLFftrHP%Ric#+M{S?k2P(Mv>-Yd2Yh-Vs)*84)L`&jUVbyP5 z5feVD2u#8X6G*WnPY}4&)6Gn&e((&@QXg-PpIXed{&_`|T1YF;QXGg>a+L|3t*gJa z8NutKSbcaM`JFxKU8#>4>-FpK<|i9lQe`yS8fhJ*65kzd6`_sMrfkF-cC@*^a`}H< eKA!vs_~PF6yZ0X4{q(b;rz~lB>C)zvt>J%O`;>D4 diff --git a/test/accessibility/pdf/image_jpg.pdf b/test/accessibility/pdf/image_jpg.pdf index 6b70c268d983c212f27197b3a6887850ec4a902d..cb004bbd22b7faeef909a5337fd27a96303d9369 100644 GIT binary patch delta 560 zcmaiwy-EW?5P%UCWP|1^HHCNvf><2x&+N?Z5fAPpYvWIoLWC4z60B0h6zNjfS*iO3 zK7q(RhOgi=h*e4vMG$Tary9QbW|*0|dw2J@EaR66KI zMG$&6WFUSI#J`6i=s+Z?gUv}2`nTpm&m5x8xlx49<^Vdkd10*U06NEWnZ<4UpVDJl W#%?B;Y97%~G2S*z7KbL8=+9;hse9 zMHGAv5eu<2Y7xj3Znga8&+N>;6`#dpwS|b9(E%8Gx_{r^ocC_atMdA;tgH4g!X9Ez z^9WrZpl_&oX>&_xy%SvuY#yTXjh1abc1P>WuFdh@^V*?{;pfC_vJV*3f46pLT$^>&3XHac z@ys%mW!wnuGG$z5jD7evU^x*WowtRd&fCIpX&2t2UC8oWVxDD4lav}XD?&+-2?xnm gF~!)A{;h12I3~xvy>9Qc+dd#dAs3|C%r zw=yuWGBw$JkRWAE?)xW5^g9 zpgYXK#MlJG1QSa$BXqqcmKGQ;H#IQ8B4z}2r5VEarUvF1-Z8Z_#_+bOrK!PW$%i)a zmPRgyrp^YACg#RYhHg%V7Dg^cM#korPC)0nn3);aDcBHH63b<0$5mXCSX5F`l$yq6 P3JgADE>%@me>W}wL&$$R diff --git a/test/accessibility/pdf/image_svg.pdf b/test/accessibility/pdf/image_svg.pdf index 94720f5648923007ef43197374786ae6eedd5465..c3fce5b0e3b7ef18796ad1196a0535563af509e2 100644 GIT binary patch delta 685 zcmaiwze)o^5QhnpW`pKbP}0aEL}C##Gy6Y;fM@Q~X`z)MA|`5;Kulqm!p=(BC-4bG z(%9MyHu@eufQV6p#cjZ?mT!LZ&FsGRpZhnX0s)di1XTEN{XU=X_NwjJUoFI|R0XV( z*+;Ac))gK!YMqmM$KORIe_vejh2m$F&G=Gu9>DQ!w2{lv_;K-UZR)SUix*g8oY&fW zM4ZTfKqZfkqZ_yJZEjO?_&&VH+0O-uvGe@qRzMjINFgC)F53%I%IuRS%(=MSw*N@+wqnWDW*x>SWhj(% KtXxiZQ}zWpy_LZL delta 678 zcmaixO-n*S6o!##;Ygy1+ZqBR7s5I7J)#%9S6voF+vtOgD7Y8Q(B0h!K{3B1?%xP1 z=ufnZenIxJkUK)dEQaSCp7(`$O5T$Dw1kLEpaziU@%Ce_IBVU+S8+0pU0Mz+*g|YE zae%rF(3U29EsKIjUA=PQ!R)TGT_`CsiqDeMOTw5tu8Qol+T2*kpzyqkmZEj*xKm_| z&M(k?_YRv`A756QhQjxuF(p3_WK3y~39emN?xtFJBdyV6M$S`mS}RnZabVJ8%y>S| z?JsjgZPmSYTq3xhs&(__KyaJi1|cNmLSc@$dr-C1H%PIBEwQR4Rt?-s(kjo8f%$7x zUibzCbf`N=0{YgPkcAMjXwZuy9u1VxLuNx6nIR8o=iik>5(MOWax$LG#-nqBTuMzE JjltfKd;yyQmTCY1 diff --git a/test/accessibility/pdf/image_wmf.pdf b/test/accessibility/pdf/image_wmf.pdf index 4b6eb082763d0daed1c4c87e217a142f455f89fd..b9ec8c55a94705110a05e96087cb5505c361e272 100644 GIT binary patch literal 304960 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

No`KPQB|wHD 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⋘#U6y6%cXw3W#h*} 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

38sA+ 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 literal 208454 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

e%8_r;>#ZCTw7j>}Sz4TeK2|-g{P_L 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 a|B0VsR%>Peudz{Fg#R}$UYz`N+WZAr2^D<+ diff --git a/test/accessibility/pdf/leader.pdf b/test/accessibility/pdf/leader.pdf index 4a6c25253dac586b8707175e1dee25072ddf2980..c7432e751e99872f83c8a230dffc05c25dfd030c 100644 GIT binary patch delta 533 zcmZ4NIooqWJ-3m8p^>?vp@E^P$;Pe^ysW8ty6#SsoB5o?jdTqRb&bqJ3=ORe46RH} zqHOe2lC4rEFBFiRyq;fdGB^J}0dzH!B?U4t1UF9WCr<>LfZ<3JOA9QjEiv3+ zYG7(P`Ju9~D2A8JjV+BQbE??Hxj7q~I02!Vv4Nq9k(r~Lv$LCtk)x5Tfw7T`fvJ(5 if(=0>v0Qd`T*W1cMI{wQscBpmW|rn$s;aL3Zd?F4?syph delta 586 zcmaiwyGq1R5QbT?@rWU?SPEfv1&hGUIdg8Zq)1F4h1l3wD6ZfIgb3@3+ocy4gp`&( zf#e13t$Y(-K=4*5I|~j|4ByQB|1b~bV|iaMBcddSiOf);g8SQ3eNfDDJL(~k{yEX54(oDgdIn1$L z4ZtqaFy~pynjeqg&sUYVO=n|pgt(z%p6@YydW- zIYx{DW2H`-d;N>J?;nDyf2^$ea^*cJdVDpwV&d#R=!qri=NoVSc}vV*H%p~mX+!vY z;V=}74;Zk9X;MYLzTKSwi;z=HQ${mQ8=h-)#C%S&Tnq4}9sOWhQ_ ITC3X@A0ug=1ONa4 delta 731 zcmaixu}T9$5Qa%5t{SefQIG>Y3*lgAZ+3Q8EKLBnozFJS!^ja7@n*WUL^w4Uv6Z=7T%*1sn%Vzqo|r#%Q}2*SbP zsABPBbtW03VB}=3bFz}pL@sOiV;3u%3{sGhgc&B|nr7H(7wG7?GBTW{C(KZILNsD> zWZ5@Mp>;Bskd|@P+Srj7OK7YD+1n-~mOT>7fs@ywFnP14Hz~taqQ~GmmYMZA5c(c; nx;>^oc(6D?CZIe%`#0oT<+*yA+?11Pd3&eW1FIzIj|S=o$GV*O diff --git a/test/accessibility/pdf/role.pdf b/test/accessibility/pdf/role.pdf index ec5d5f5366923bd5a1f3e6790fee839568f072b5..acb43502799635bd258ce2b96cfb7bf5409b1960 100644 GIT binary patch delta 1479 zcmah}OKTHR6lR3lB()}Vs(m3$7Yzu8-q*SJPEC`{G>OSV#o|JIAYv=73f3;%MG-e$ zDW?mUx^p3lWaD3OC3d5rdvW384=CPb3U=lcoXs8X{m%Km@0@$?vmNj0j`z4XCKwln zbH)MQZ2uY`S>LFfiSgmlcuG_luLyII^CiZY04`S-*KRJY;q%fAzAhfevErXn7K1aT z+hnuA#h`qj`}4r0L`7tB3Gd zV=6C95-R$+n(tvJ@^P{L5=Ubnf7Z*`s7>OjM$Q9-hV_~l#gm@G?S{c(l=CEdW**;% zMVwoiz;BH*-jDLwiN{BVM0hrmLmcekO8D8~UPNX5u{?cP+5t5liL0K$ZoG?gbssA$ zukcHK0>7_(Jt+b<_=1g~F#O??8z6g9as1sp*E6mp890QlFqu7lKnkO2Y{*@0)3J&P zLa(??Vte~^DkTW9f`Q*mLVEx%q&Q$eY5`oQ#N=FR4ni}$(Dr*oJE%eP)ARt0$OO&Z zjmY41n4)s094sStz=nGqy?;G}&=N740V%lSB_6c^cbC&*wA7O9DU}w}a|*R91_A25 zZtZK9Hq^1UgUQMehnxxwLsBin3{a-t1!#oRa$r-B=eA6$m4U#2Z>rjQ}ACbVKW-=!M3P>S3oVQEW+wG!`ieUIUz zZuPpG{ARn!T2T{(2^ll)ofWdx;*vFix1knP{|mWRsMQL0w{C21-P>HhRd8>Kk%fhY I*7h9r{HcvwYDOjmz*%zn)5CTpv`(CpByzns}NL-${ zT4W+7@#UDQEO62dGz-*p_n`fG;>+<~|Mpw9JCJAlAlcqJcRhzcl5zZ7I?^629}94# z7U5)N2X}4!SviG!rSUvtT{ex=RgIPMz*v_djN|DG@ioS~+Y&dc3b)dHoZ%04voUXk z<#HIVH1Dq7c@Q$ZRGQ2&j_+p)PE;aXOp2Yl6Mc1=uKqfOOQkb8CbPn?ws1H-8&IsK zyZEa*g2mb!+(}08du?x2#-#Jb%{a^!z(5)NR*wRMf9i{6ZRs6=B-R%? z=c1PNxPOO}j#Ew!xYvpEj(-kLaBpO;55buOT&t%|5NVIUpHP7Eh7nY1568GCMDWg; zI(!29hn^+`grxR(9iSq9V+|5N%ts~93t@CWt!0&m$dRBp4xf)&KAK6-Imv}5Knmsw zm6q0>Un=IADK*(Q?q<(*X(+hGiV$xYMYK1J0^>DSR0#|kof|sZI5}o~azQ9AHKLMB zN9>JqwGpYn!&z+tUpJzbcWM;0tJ*RsR}7I_`?dDsyGBsS-R|~Hr2Dy{o{N-ogULd4 z+Vg{I|0ku!aNJy&y=9U#(SmALCw053r8O=S#gf!0n$8hkj%WW1$sU(S>$lg|H`Z3} Pg`k9nuvnbCI3NB4TqH+E diff --git a/test/accessibility/pdf/role_non-standard.pdf b/test/accessibility/pdf/role_non-standard.pdf index d906930668912b0b56847b26d459772a7cc9c39b..fcf614ed11e4862586f4915e8076d13f55fe9ba1 100644 GIT binary patch delta 1514 zcmah|J#W-N5S2kd&I!qJ4*3#=C3Jy+j_l6v?5=aio$n5ZL$NBNlBB2jsQA|zd*-VLw*4uDyS&<5cXM!i#HN()*8R@y!Ynq=DPD_-FX=I1LL4M zXB^dw2VeK^Sz4}~ZqeFcYZNMsS3qCne1`EER99-#i#KN$X`?t!&xS^*f9Q8HkD>A6 zZL8RMRNN{!KzAlCmm%<(f58_#J7jjK?jc!rKMlAQ zjut>?t8^#n4k~Ue#R`-qP6?gGB<{(HlFA~Z z&{nKew!3YEwXIkgX_L<7V{dA|X5`Fy4Q6^ble)(>FiWEbW0|W(fOLHBNNfqv$nxu9 zQdpu`lD#}xrZntOlX-^|+~1rH{JV9)>D!zaYm>i^Oqn463l5T7O9Evl5Nw)Bud)II zMt5Zo_AUtw-H*K8j3Lo{?RpeNa0;3b047cw-A->pE0VLIA~hTFx?lS*b?npw&8Y8(lB1^nPyZWQLJ0JU*F^Z@t9t0!m!5|1L#E7{KUJZhz za`6v%Ga!5PpnoA=;!zOv8c+}7#on1nvQrDrrH9wAy56g*?l)Vd?XA+Q^cVn04OW0q z?_TVUl-FmTb{=&eKkHCB+8ToyfElT8f}IsGD^z!9RF@b^6Jrk<*nK(nxm-e8nYvX~ zCKmCHSlMjRB41>-NT2UP_v_T|$%Fje4{B$)toBLReLc54L_eF8L(+C9YLybj?F!A- z-_n<`{;p5cuZ797Qu$$y78;J?#_);!fGCd7Uyg4poo^#;G%Ve#AFbp8|F$!kn@zPj zH$0>??X?7*tygHdSsg&m%+SYuHfHSafqklVt|aMd>l6KHjFW0_)BEN){b+wXE+H1Z zFYd%q_5%v&dQv%}P}7m*N@_%~TVNoBL`BRyhFQ;Jea~=ztQMNZYQRicdRUs)8dUwyC=fi>Pl)oOC>Li88+uuWV5 diff --git a/test/accessibility/pdf/text_1.pdf b/test/accessibility/pdf/text_1.pdf index 0b1e1ee9ff6a25a533a25779a41ac05536606d7d..596419c9db2cf9d33d28f8e40981aa8d0a02d1d6 100644 GIT binary patch delta 489 zcmca$b;4>wJ-3m8p^>?vp@E^P`NpmfysW8ty6#SsoB5o?jdTqRb&bqJ3=ORe46RJf zqipn3lC4rEFBFiRyq;fdGB^J}0dzH!B?U4t1UF9YLkzv9mIjlVWYld; zF=Q;vF~m%aO$^Z0nHXD6UMM4MXJ~;gV``4+R#S6R4ELLwTNq5?&>-n4n40R0+b&X6y49%?! z46O`IHecj3VZ;!fEGm$JA-K6$;3X@g+2nGu?+8OT7mM#@*0MBIFaQCCJOwT=!@$(i z)Bs(~%+SbSa+I`Rkcl~ll(C5khM0+wDTbJ-p(Uo6rN!i5((3h?G8Pub=&DVy*kodC ziQytsb0Z^ky{6_S80MLpn?c3+kbG}$VKRB0j7^-mv#Xnlg|oAv0Qd`T*W1cMI{wQscBqhmc|BLs;aL3Zd?F)1afi! diff --git a/test/accessibility/pdf/text_2.pdf b/test/accessibility/pdf/text_2.pdf index 3330cc902cf92dc48b92be253378cb747d9957dd..19fff21a438f0ab4223b1de2202410b6ddd121ec 100644 GIT binary patch delta 628 zcmaiwze)o^5XKQrvq5u}5)eFvL{c2??9T4o93e%#oRyfuN>C9Ku}TqB*riBkrEFpC z6NubfSmhZkQ|Swc8XLI{xYg`$zWMXbtozozAD5K`MF0{^{BrlcTIvs?gSMNjwKr5G zAyRY7f^M~NEyrlBRX1?rRw?#hN`Y1Ip zls_*Vgkm1Z7`}f+rmS@<^~14d?d6c!VfM6ePUsqQq@pXAoUfz^-)!7X& zMvOHbAa?<~V4KGdwFIr#f^z|zyI|UGxh7g~mVT}_PaAK`J4py%6PBTxFOVRRV4A6Z zkM=486qyBd#4j>3Bs7S~E%q4s59WmuYy4)% zzkbC|da^dcoiz(5_9%YI-e5i3?j5nWdVm0&^#@sI6Eb;W`bOskd^(Uz!`{D@LzSlL VYJ4&pPe!L_$~&u76y^Jc`T!T4ig^G4 diff --git a/test/accessibility/pdf/text_font-embedding.pdf b/test/accessibility/pdf/text_font-embedding.pdf index a268dbb63bfabfaa90e01cd7a5ec96b2b67244c0..0288449d5baf0eec5ef036c0b4274d56861ee194 100644 GIT binary patch delta 668 zcmaiwF-rqM5QPb1;RVfAO1f);2p*Z)o15JY;lPtSK}A8tA|N6rVwEDMuuEZQrEHhZ z%1)7hg`K7UM6CP;VvHhOrf{p}+qZAto7Z9KWmvi%log=Th=8$uy!x1*?R3M9)Lky5 zODY5mmEK2e05)RVYS!B)jkde>tL~w)=*pE(e_G?J{+WQI8~|2of_P|4I(MB=OGs$G!eVuXF051yWwEmhI-=7stVp AW&i*H delta 662 zcmaixF-rqM5QRCcvSLVMVRuas!NZxk+1YFe2T8~kDhfgDL@X3RI3Y$%cfBA8*QH5k zuLt&)mi`ATD}RC*M9EFzRLeJS-s7<^)8KU)+~>=PNQ@2;hqXY;_qFHEKi6`Wek^Uc5WXkOLNkA03rG}0 zFU8aL-jG7|@h)A^# zh$mG?Vpk18VOB*%pj8P*@otfA0ig4szQTE06wY<*iih3Kv6ZynCrgAL*;z`h9pJ#* kUbmaJY@d>_^RMK{B#F5ipNz(n(dn5%4;D - + - + - + - + - + - + Apache FOP (Formatting Objects Processor) is a print formatter driven by XSL formatting objects (XSL-FO) and an output independent formatter. It is a Java application diff --git a/test/accessibility/text_2.fo b/test/accessibility/text_2.fo index 5eff059b6..f5693110e 100644 --- a/test/accessibility/text_2.fo +++ b/test/accessibility/text_2.fo @@ -16,14 +16,14 @@ limitations under the License. --> - + - + Apache FOP (Formatting Objects Processor) is a print formatter driven by XSL formatting objects (XSL-FO) and an output independent formatter. It is a Java application diff --git a/test/accessibility/text_font-embedding.fo b/test/accessibility/text_font-embedding.fo index 1d3abe027..10c1c99d9 100644 --- a/test/accessibility/text_font-embedding.fo +++ b/test/accessibility/text_font-embedding.fo @@ -16,14 +16,14 @@ limitations under the License. --> - + - + Apache FOP (Formatting Objects Processor) is a print formatter driven by XSL formatting objects (XSL-FO) and an output independent formatter. It is a Java application diff --git a/test/java/org/apache/fop/accessibility/fo/DOMResultUtil.java b/test/java/org/apache/fop/accessibility/fo/DOMResultUtil.java new file mode 100644 index 000000000..5b4e264f2 --- /dev/null +++ b/test/java/org/apache/fop/accessibility/fo/DOMResultUtil.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.accessibility.fo; + +import java.io.File; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +/** + * Utility class to stream an instance of {@link DOMResult} into a file. May be + * useful for debugging. + */ +final class DOMResultUtil { + + private DOMResultUtil() { + } + + /** + * Streams the given result into a file of the given name. + * + * @param result the result of a transformation + * @param filename name of the file into which to stream the result + * @throws TransformerException if a problem occurs when streaming + */ + public static void streamToFile(DOMResult result, String filename) throws TransformerException { + DOMSource source = new DOMSource(result.getNode()); + TransformerFactory tFactory = TransformerFactory.newInstance(); + Transformer transformer = tFactory.newTransformer(); + transformer.transform(source, new StreamResult(new File(filename))); + } + +} diff --git a/test/java/org/apache/fop/accessibility/FO2StructureTreeConverterTestCase.java b/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java similarity index 68% rename from test/java/org/apache/fop/accessibility/FO2StructureTreeConverterTestCase.java rename to test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java index f8719edd6..9c53bdde3 100644 --- a/test/java/org/apache/fop/accessibility/FO2StructureTreeConverterTestCase.java +++ b/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java @@ -17,10 +17,12 @@ /* $Id$ */ -package org.apache.fop.accessibility; +package org.apache.fop.accessibility.fo; import static org.junit.Assert.assertTrue; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -34,18 +36,17 @@ import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import org.custommonkey.xmlunit.Diff; -import org.custommonkey.xmlunit.Difference; -import org.custommonkey.xmlunit.DifferenceConstants; -import org.custommonkey.xmlunit.DifferenceListener; import org.junit.Test; import org.w3c.dom.Document; -import org.w3c.dom.Node; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; +import org.apache.fop.accessibility.StructureTree2SAXEventAdapter; +import org.apache.fop.accessibility.StructureTreeEventHandler; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fo.FODocumentParser; @@ -56,54 +57,75 @@ import org.apache.fop.fotreetest.DummyFOEventHandler; public class FO2StructureTreeConverterTestCase { - private static class IgnoringPtrDifferenceListener implements DifferenceListener { - - public int differenceFound(Difference difference) { - switch (difference.getId()) { - case DifferenceConstants.ELEMENT_NUM_ATTRIBUTES_ID: - return RETURN_IGNORE_DIFFERENCE_NODES_SIMILAR; - case DifferenceConstants.ATTR_NAME_NOT_FOUND_ID: - String additionalAttribute = difference.getTestNodeDetail().getValue(); - if (additionalAttribute.equals("ptr")) { - return RETURN_IGNORE_DIFFERENCE_NODES_SIMILAR; - } else { - return RETURN_ACCEPT_DIFFERENCE; - } - default: - return RETURN_ACCEPT_DIFFERENCE; - } - } + private interface FOLoader { - public void skippedComparison(Node control, Node test) { - throw new UnsupportedOperationException("Not implemented"); - } + InputStream getFoInputStream(); } private static final String STRUCTURE_TREE_SEQUENCE_NAME = "structure-tree-sequence"; + private FOLoader foLoader; + + @Test + public void testCompleteDocument() throws Exception { + foLoader = new FOLoader() { + public InputStream getFoInputStream() { + return getResource("/org/apache/fop/fo/complete_document.fo"); + } + }; + testConverter(); + } + + @Test + public void testTableFooters() throws Exception { + foLoader = new FOLoader() { + public InputStream getFoInputStream() { + return getResource("table-footers.fo"); + } + }; + testConverter(); + } + @Test - public void testConverter() throws Exception { + public void testCompleteContentWrappedInTableFooter() throws Exception { + Source xslt = new StreamSource(getResource("wrapCompleteDocumentInTableFooter.xsl")); + Transformer transformer = createTransformer(xslt); + InputStream originalFO = getResource("/org/apache/fop/fo/complete_document.fo"); + ByteArrayOutputStream transformedFoOutput = new ByteArrayOutputStream(); + transformer.transform(new StreamSource(originalFO), new StreamResult(transformedFoOutput)); + final byte[] transformedFoOutputBytes = transformedFoOutput.toByteArray(); + foLoader = new FOLoader() { + public InputStream getFoInputStream() { + return new ByteArrayInputStream(transformedFoOutputBytes); + } + }; + testConverter(); + } + + private Transformer createTransformer(Source xslt) throws TransformerFactoryConfigurationError, + TransformerConfigurationException { + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + return transformerFactory.newTransformer(xslt); + } + + private static InputStream getResource(String name) { + return FO2StructureTreeConverterTestCase.class.getResourceAsStream(name); + } + + private void testConverter() throws Exception { DOMResult expectedStructureTree = loadExpectedStructureTree(); DOMResult actualStructureTree = buildActualStructureTree(); final Diff diff = createDiff(expectedStructureTree, actualStructureTree); - assertTrue(diff.toString(), diff.similar()); + assertTrue(diff.toString(), diff.identical()); } - private static DOMResult loadExpectedStructureTree() { + private DOMResult loadExpectedStructureTree() { DOMResult expectedStructureTree = new DOMResult(); - runXSLT(getXsltInputStream(), getFoInputStream(), expectedStructureTree); + InputStream xslt = getResource("fo2StructureTree.xsl"); + runXSLT(xslt, foLoader.getFoInputStream(), expectedStructureTree); return expectedStructureTree; } - private static InputStream getXsltInputStream() { - return FO2StructureTreeConverterTestCase.class.getResourceAsStream("foToIfStructureTree.xsl"); - } - - private static InputStream getFoInputStream() { - return FO2StructureTreeConverterTestCase.class.getResourceAsStream( - "/org/apache/fop/fo/complete_document.fo"); - } - private static void runXSLT(InputStream xslt, InputStream doc, Result result) { Source fo = new StreamSource(doc); try { @@ -128,15 +150,15 @@ public class FO2StructureTreeConverterTestCase { } } - private static DOMResult buildActualStructureTree() throws Exception { + private DOMResult buildActualStructureTree() throws Exception { DOMResult actualStructureTree = new DOMResult(); - createStructureTreeFromDocument(getFoInputStream(), actualStructureTree); + createStructureTreeFromDocument(foLoader.getFoInputStream(), actualStructureTree); return actualStructureTree; } private static void createStructureTreeFromDocument(InputStream foInputStream, - DOMResult domResult) throws Exception { - TransformerHandler tHandler = createTransformerHandler(domResult); + Result result) throws Exception { + TransformerHandler tHandler = createTransformerHandler(result); startStructureTreeSequence(tHandler); StructureTreeEventHandler structureTreeEventHandler = StructureTree2SAXEventAdapter.newInstance(tHandler); @@ -146,7 +168,7 @@ public class FO2StructureTreeConverterTestCase { endStructureTreeSequence(tHandler); } - private static TransformerHandler createTransformerHandler(DOMResult domResult) + private static TransformerHandler createTransformerHandler(Result domResult) throws TransformerConfigurationException, TransformerFactoryConfigurationError { SAXTransformerFactory factory = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); TransformerHandler transformerHandler = factory.newTransformerHandler(); @@ -192,7 +214,6 @@ public class FO2StructureTreeConverterTestCase { private static Diff createDiff(DOMResult expected, DOMResult actual) { Diff diff = new Diff(getDocument(expected), getDocument(actual)); - diff.overrideDifferenceListener(new IgnoringPtrDifferenceListener()); return diff; } diff --git a/test/java/org/apache/fop/accessibility/fo2StructureTree.xsl b/test/java/org/apache/fop/accessibility/fo/fo2StructureTree.xsl similarity index 84% rename from test/java/org/apache/fop/accessibility/fo2StructureTree.xsl rename to test/java/org/apache/fop/accessibility/fo/fo2StructureTree.xsl index 5c9c5615c..ce326f3b1 100644 --- a/test/java/org/apache/fop/accessibility/fo2StructureTree.xsl +++ b/test/java/org/apache/fop/accessibility/fo/fo2StructureTree.xsl @@ -69,10 +69,18 @@ - + + + + + + + + + @@ -110,7 +118,18 @@ - + + + + + + diff --git a/test/java/org/apache/fop/accessibility/fo/table-footers.fo b/test/java/org/apache/fop/accessibility/fo/table-footers.fo new file mode 100644 index 000000000..6dcb9b68d --- /dev/null +++ b/test/java/org/apache/fop/accessibility/fo/table-footers.fo @@ -0,0 +1,195 @@ + + + + + + + + + + + + + Start Outer Header + + + + Inner Header 1.1 + + + Inner Header 1.2 + + + + + Inner Footer 1.1 + + + Inner Footer 1.2 + + + + + + Inner Body 1.1 + + + Inner Body 1.2 + + + + + Inner Body 2.1 + + + Inner Body 2.2 + + + + + End Outer Header + + + + + Start Outer Footer + + + + Inner Header 1.1 + + + Inner Header 1.2 + + + + + Start Inner Footer 1.1 + + + + Inner Inner Header 1.1 + + + Inner Inner Header 1.2 + + + + + Inner Inner Footer 1.1 + + + Inner Inner Footer 1.2 + + + + + + Inner Inner Body 1.1 + + + Inner Inner Body 1.2 + + + + + Inner Inner Body 2.1 + + + Inner Inner Body 2.2 + + + + + End Inner Footer 1.1 + + + Inner Footer 1.2 + + + + + + Inner Body 1.1 + + + Inner Body 1.2 + + + + + Inner Body 2.1 + + + Inner Body 2.2 + + + + + End Outer Footer + + + + + + Outer Body Cell 1 + + + + + Start Outer Body Cell 2 + + + + Inner Footer 1.1 + + + Inner Footer 1.2 + + + + + Inner Header 1.1 + + + Inner Header 1.2 + + + + + + Inner Body 1.1 + + + Inner Body 1.2 + + + + + Inner Body 2.1 + + + Inner Body 2.2 + + + + + End Outer Body Cell 2 + + + + + + + diff --git a/test/java/org/apache/fop/accessibility/fo/wrapCompleteDocumentInTableFooter.xsl b/test/java/org/apache/fop/accessibility/fo/wrapCompleteDocumentInTableFooter.xsl new file mode 100644 index 000000000..9608b2fb9 --- /dev/null +++ b/test/java/org/apache/fop/accessibility/fo/wrapCompleteDocumentInTableFooter.xsl @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The content below is in the table footer. + + + + + + + diff --git a/test/java/org/apache/fop/render/intermediate/IFStructureTreeBuilderTestCase.java b/test/java/org/apache/fop/render/intermediate/IFStructureTreeBuilderTestCase.java index d7db7db7f..65c6b25a6 100644 --- a/test/java/org/apache/fop/render/intermediate/IFStructureTreeBuilderTestCase.java +++ b/test/java/org/apache/fop/render/intermediate/IFStructureTreeBuilderTestCase.java @@ -85,7 +85,7 @@ public class IFStructureTreeBuilderTestCase { @Test public void startNode() throws Exception { - final String[] attributes = {"ptr", "1"}; + final String[] attributes = {"struct-id", "1"}; final String nodeName = "block"; final ContentHandler handler = mock(ContentHandler.class); -- 2.39.5