diff options
author | Vincent Hennebert <vhennebert@apache.org> | 2010-01-13 17:05:59 +0000 |
---|---|---|
committer | Vincent Hennebert <vhennebert@apache.org> | 2010-01-13 17:05:59 +0000 |
commit | 91cdef3c3337a3e2537be2136a98eb7a7b46cebe (patch) | |
tree | f48386a5e01d5fa6cb5942feacb9cbb37db4716a | |
parent | 27166d6f10d109d339a120e0625073b43c1bf01b (diff) | |
download | xmlgraphics-fop-91cdef3c3337a3e2537be2136a98eb7a7b46cebe.tar.gz xmlgraphics-fop-91cdef3c3337a3e2537be2136a98eb7a7b46cebe.zip |
Added possibility to customize PDF tagging via the role property
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@898840 13f79535-47bb-0310-9956-ffa450edef68
19 files changed, 443 insertions, 65 deletions
diff --git a/src/documentation/content/xdocs/trunk/accessibility.xml b/src/documentation/content/xdocs/trunk/accessibility.xml index 1eb78264b..f3c66e06a 100644 --- a/src/documentation/content/xdocs/trunk/accessibility.xml +++ b/src/documentation/content/xdocs/trunk/accessibility.xml @@ -91,6 +91,26 @@ </li> </ul> </section> + <section id="customTags"> + <title>Customized Tagging</title> + <p>The <a href="#PDFReference">PDF Reference</a> defines a set of standard Structure Types to + tag content. For example, ‘P’ is used for identifying paragraphs, ‘H1’ to ‘H6’ for headers, + ‘L’ for lists, ‘Div’ for block-level groups of elements, etc. This standard set is aimed at + improving interoperability between applications producing or consuming PDF. </p> + <p>FOP provides a default mapping of Formatting Objects to elements from that standard set. + For example, <code>fo:page-sequence</code> is mapped to ‘Part’, <code>fo:block</code> is + mapped to ‘P’, <code>fo:list-block</code> to ‘L’, etc.</p> + <p>You may want to customize that mapping to improve the accuracy of the tagging or deal with + particular FO constructs. For example, you may want to make use of the ‘H1’ to ‘H6’ tags to + make the hierarchical structure of the document appear in the PDF. This is achieved by using + the <code>role</code> XSL-FO property:</p> + <source>... +<fo:block role="H1" font-weight="bold">I. A Level 1 Heading</fo:block> +<fo:block>This is the first paragraph of the first section...</fo:block> +...</source> + <p>If a non-standard structure type is specified, FOP will issue a warning and fall back to + the default tag associated to the Formatting Object.</p> + </section> <section id="testing"> <title>Testing</title> <p> @@ -120,11 +140,6 @@ SVGs is not accessible. It's only possible to work with <code>fox:alt-text</code>. </li> <li> - XSL-FO's role property is currently not supported. It could theoretically be used to - differentiate between headings and normal text. At the moment, the two are simply - identified as paragraphs. - </li> - <li> The side regions (region-before, region-after etc.) are currently not specially identified. Screen readers may read their content at page changes. </li> @@ -140,7 +155,7 @@ <li><a href="http://www.section508.gov/">US Government - Website on Section 508</a></li> <li><a href="http://en.wikipedia.org/wiki/Accessibility">Wikipedia on Accessibility in general</a></li> <li><a href="http://en.wikipedia.org/wiki/Portable_Document_Format#Accessibility">Wikipedia on Accessibility in PDF</a></li> - <li> + <li id="PDFReference"> <a href="http://partners.adobe.com/public/developer/en/pdf/PDFReference.pdf">PDF Reference 1.4</a> (look up chapters 9.7 "Tagged PDF" and 9.8 "Accessibility Support") </li> diff --git a/src/java/org/apache/fop/accessibility/reduceFOTree.xsl b/src/java/org/apache/fop/accessibility/reduceFOTree.xsl index 8e9bcfc13..0d93a2506 100644 --- a/src/java/org/apache/fop/accessibility/reduceFOTree.xsl +++ b/src/java/org/apache/fop/accessibility/reduceFOTree.xsl @@ -86,8 +86,8 @@ <xsl:template match="fo:leader"/> - <!-- Keep foi:ptr and fox:alt-text attributes, discard everything else --> - <xsl:template match="@foi:ptr|@fox:alt-text"> + <!-- Keep foi:ptr, fox:alt-text and role attributes, discard everything else --> + <xsl:template match="@foi:ptr|@fox:alt-text|@role"> <xsl:copy-of select="."/> </xsl:template> diff --git a/src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java b/src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java index 2c13edca5..26595bca1 100644 --- a/src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java +++ b/src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java @@ -19,8 +19,12 @@ package org.apache.fop.render.pdf; +import java.util.HashMap; import java.util.Map; +import org.w3c.dom.Node; + +import org.apache.fop.events.EventBroadcaster; import org.apache.fop.pdf.PDFName; import org.apache.fop.pdf.PDFObject; import org.apache.fop.pdf.PDFStructElem; @@ -30,71 +34,137 @@ import org.apache.fop.pdf.PDFStructElem; */ final class FOToPDFRoleMap { - private static final Map STANDARD_MAPPINGS = new java.util.HashMap(); - - private static final PDFName TFOOT = new PDFName("TFoot"); - private static final PDFName THEAD = new PDFName("THead"); - private static final PDFName NON_STRUCT = new PDFName("NonStruct"); - - static { - addMapping("block", "P"); + /** + * Standard structure types defined by the PDF Reference, Fourth Edition (PDF 1.5). + */ + private static final Map STANDARD_STRUCTURE_TYPES = new HashMap(); - PDFName st = new PDFName("Div"); - addMapping("block-container", st); - addMapping("inline-container", st); - addMapping("table-and-caption", st); - addMapping("float", st); + private static final Map DEFAULT_MAPPINGS = new java.util.HashMap(); - st = new PDFName("Span"); - addMapping("inline", st); - addMapping("wrapper", st); - addMapping("character", st); + private static final PDFName THEAD; + private static final PDFName NON_STRUCT; + static { + // Create PDFNames for the standard structure types + // Table 10.18: Grouping elements + addStructureType("Document"); + addStructureType("Part"); + addStructureType("Art"); + addStructureType("Sect"); + addStructureType("Div"); + addStructureType("BlockQuote"); + addStructureType("Caption"); + addStructureType("TOC"); + addStructureType("TOCI"); + addStructureType("Index"); + addStructureType("NonStruct"); + addStructureType("Private"); + // Table 10.20: Paragraphlike elements + addStructureType("H"); + addStructureType("H1"); + addStructureType("H2"); + addStructureType("H3"); + addStructureType("H4"); + addStructureType("H5"); + addStructureType("H6"); + addStructureType("P"); + // Table 10.21: List elements + addStructureType("L"); + addStructureType("LI"); + addStructureType("Lbl"); + addStructureType("LBody"); + // Table 10.22: Table elements + addStructureType("Table"); + addStructureType("TR"); + addStructureType("TH"); + addStructureType("TD"); + addStructureType("THead"); + addStructureType("TBody"); + addStructureType("TFoot"); + // Table 10.23: Inline-level structure elements + addStructureType("Span"); + addStructureType("Quote"); + addStructureType("Note"); + addStructureType("Reference"); + addStructureType("BibEntry"); + addStructureType("Code"); + addStructureType("Link"); + addStructureType("Annot"); + // Table 10.24: Ruby and Warichu elements + addStructureType("Ruby"); + addStructureType("RB"); + addStructureType("RT"); + addStructureType("RP"); + addStructureType("Warichu"); + addStructureType("WT"); + addStructureType("WP"); + // Table 10.25: Illustration elements + addStructureType("Figure"); + addStructureType("Formula"); + addStructureType("Form"); + + NON_STRUCT = (PDFName) STANDARD_STRUCTURE_TYPES.get("NonStruct"); + assert NON_STRUCT != null; + THEAD = (PDFName) STANDARD_STRUCTURE_TYPES.get("THead"); + assert THEAD != null; + + // Create the standard mappings + // Declarations and Pagination and Layout Formatting Objects addMapping("root", "Document"); addMapping("page-sequence", "Part"); addMapping("flow", "Sect"); addMapping("static-content", "Sect"); - - st = new PDFName("Quote"); - addMapping("page-number", st); - addMapping("page-number-citation", st); - addMapping("page-number-citation-last", st); - - st = new PDFName("Figure"); - addMapping("external-graphic", st); - addMapping("instream-foreign-object", st); - - addMapping("table-caption", "Caption"); + // Block-level Formatting Objects + addMapping("block", "P"); + addMapping("block-container", "Div"); + // Inline-level Formatting Objects + addMapping("character", "Span"); + addMapping("external-graphic", "Figure"); + addMapping("instream-foreign-object", "Figure"); + addMapping("inline", "Span"); + addMapping("inline-container", "Div"); + addMapping("page-number", "Quote"); + addMapping("page-number-citation", "Quote"); + addMapping("page-number-citation-last", "Quote"); + // Formatting Objects for Tables + addMapping("table-and-caption", "Div"); addMapping("table", "Table"); + addMapping("table-caption", "Caption"); + addMapping("table-header", "THead"); + addMapping("table-footer", "TFoot"); addMapping("table-body", "TBody"); - addMapping("table-header", THEAD); - addMapping("table-footer", TFOOT); addMapping("table-row", "TR"); addMapping("table-cell", new TableCellMapper()); - + // Formatting Objects for Lists addMapping("list-block", "L"); addMapping("list-item", "LI"); - addMapping("list-item-label", "Lbl"); addMapping("list-item-body", "LBody"); - + addMapping("list-item-label", "Lbl"); + // Dynamic Effects: Link and Multi Formatting Objects addMapping("basic-link", "Link"); + // Out-of-Line Formatting Objects + addMapping("float", "Div"); addMapping("footnote", "Note"); addMapping("footnote-body", "Sect"); + addMapping("wrapper", "Span"); addMapping("marker", "Private"); } - private static void addMapping(String fo, String pdfName) { - addMapping(fo, new PDFName(pdfName)); + private static void addStructureType(String structureType) { + STANDARD_STRUCTURE_TYPES.put(structureType, new PDFName(structureType)); } - private static void addMapping(String fo, PDFName pdfName) { - addMapping(fo, new SimpleMapper(pdfName)); + private static void addMapping(String fo, String structureType) { + PDFName type = (PDFName) STANDARD_STRUCTURE_TYPES.get(structureType); + assert type != null; + addMapping(fo, new SimpleMapper(type)); } private static void addMapping(String fo, Mapper mapper) { - STANDARD_MAPPINGS.put(fo, mapper); + DEFAULT_MAPPINGS.put(fo, mapper); } + /** * Maps a Formatting Object to a PDFName representing the associated structure type. * @param fo the formatting object's local name @@ -102,7 +172,7 @@ final class FOToPDFRoleMap { * @return the structure type or null if no match could be found */ public static PDFName mapFormattingObject(String fo, PDFObject parent) { - Mapper mapper = (Mapper)STANDARD_MAPPINGS.get(fo); + Mapper mapper = (Mapper)DEFAULT_MAPPINGS.get(fo); if (mapper != null) { return mapper.getStructureType(parent); } else { @@ -110,7 +180,27 @@ final class FOToPDFRoleMap { } } - private interface Mapper { + public static PDFName mapFormattingObject(Node fo, PDFObject parent, + EventBroadcaster eventBroadcaster) { + PDFName type = null; + Node role = fo.getAttributes().getNamedItemNS(null, "role"); + if (role == null) { + type = mapFormattingObject(fo.getLocalName(), parent); + } else { + String customType = role.getNodeValue(); + type = (PDFName) STANDARD_STRUCTURE_TYPES.get(customType); + if (type == null) { + String foName = fo.getLocalName(); + type = mapFormattingObject(foName, parent); + PDFEventProducer.Provider.get(eventBroadcaster).nonStandardStructureType(fo, + foName, customType, type.toString().substring(1)); + } + } + assert type != null; + return type; + } + + private static interface Mapper { PDFName getStructureType(PDFObject parent); } @@ -130,18 +220,18 @@ final class FOToPDFRoleMap { private static class TableCellMapper implements Mapper { - private static final PDFName TD = new PDFName("TD"); - private static final PDFName TH = new PDFName("TH"); - public PDFName getStructureType(PDFObject parent) { PDFStructElem grandParent = (PDFStructElem) ((PDFStructElem)parent).getParentStructElem(); //TODO What to do with cells from table-footer? Currently they are mapped on TD. + PDFName type; if (THEAD.equals(grandParent.getStructureType())) { - return TH; + type = (PDFName) STANDARD_STRUCTURE_TYPES.get("TH"); } else { - return TD; + type = (PDFName) STANDARD_STRUCTURE_TYPES.get("TD"); } + assert type != null; + return type; } } diff --git a/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java b/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java index a54bbb4e7..6025fb486 100644 --- a/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java +++ b/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java @@ -145,7 +145,8 @@ public class PDFDocumentHandler extends AbstractBinaryWritingIFDocumentHandler { this.accessEnabled = getUserAgent().isAccessibilityEnabled(); if (accessEnabled) { pdfDoc.getRoot().makeTagged(); - logicalStructureHandler = new PDFLogicalStructureHandler(pdfDoc); + logicalStructureHandler = new PDFLogicalStructureHandler(pdfDoc, + getUserAgent().getEventBroadcaster()); } } catch (IOException e) { throw new IFException("I/O error in startDocument()", e); diff --git a/src/java/org/apache/fop/render/pdf/PDFEventProducer.java b/src/java/org/apache/fop/render/pdf/PDFEventProducer.java index d70409870..4d1b3a42b 100644 --- a/src/java/org/apache/fop/render/pdf/PDFEventProducer.java +++ b/src/java/org/apache/fop/render/pdf/PDFEventProducer.java @@ -66,4 +66,15 @@ public interface PDFEventProducer extends EventProducer { */ void nonFullyResolvedLinkTargets(Object source, int count); + + /** + * Custom structure type is not standard as per the PDF reference. + * + * @param source the event source + * @param fo the local name of the formatting object having the custom type + * @param type custom structure type + * @param fallback default structure type used as a fallback + * @event.severity WARN + */ + void nonStandardStructureType(Object source, String fo, String type, String fallback); } diff --git a/src/java/org/apache/fop/render/pdf/PDFEventProducer.xml b/src/java/org/apache/fop/render/pdf/PDFEventProducer.xml index fd57d5099..f6425753d 100644 --- a/src/java/org/apache/fop/render/pdf/PDFEventProducer.xml +++ b/src/java/org/apache/fop/render/pdf/PDFEventProducer.xml @@ -1,4 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> <catalogue xml:lang="en"> <message key="org.apache.fop.render.pdf.PDFEventProducer.nonFullyResolvedLinkTargets">{count} link target{count,equals,1,,s} could not be fully resolved and now point{count,equals,1,,s} to the top of the page or {count,equals,1,is,are} dysfunctional.</message> + <message key="org.apache.fop.render.pdf.PDFEventProducer.nonStandardStructureType">‘{type}’ is not a standard structure type defined by the PDF Reference. Falling back to ‘{fallback}’.</message> </catalogue> diff --git a/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java b/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java index d55094d48..42b873270 100644 --- a/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java +++ b/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java @@ -26,6 +26,7 @@ import java.util.Map; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +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.PDFArray; @@ -52,6 +53,8 @@ class PDFLogicalStructureHandler { private final PDFDocument pdfDoc; + private final EventBroadcaster eventBroadcaster; + /** * Map of references to the corresponding structure elements. */ @@ -105,8 +108,9 @@ class PDFLogicalStructureHandler { * * @param pdfDoc a document */ - PDFLogicalStructureHandler(PDFDocument pdfDoc) { + PDFLogicalStructureHandler(PDFDocument pdfDoc, EventBroadcaster eventBroadcaster) { this.pdfDoc = pdfDoc; + this.eventBroadcaster = eventBroadcaster; PDFStructTreeRoot structTreeRoot = pdfDoc.getFactory().makeStructTreeRoot(parentTree); rootStructureElement = pdfDoc.getFactory().makeStructureElement( FOToPDFRoleMap.mapFormattingObject("root", structTreeRoot), structTreeRoot); @@ -148,15 +152,15 @@ class PDFLogicalStructureHandler { Node attr = node.getAttributes().getNamedItemNS(InternalElementMapping.URI, "ptr"); assert attr != null; String ptr = attr.getNodeValue(); - String nodeName = node.getLocalName(); PDFStructElem structElem = pdfDoc.getFactory().makeStructureElement( - FOToPDFRoleMap.mapFormattingObject(nodeName, parent), parent); + FOToPDFRoleMap.mapFormattingObject(node, parent, eventBroadcaster), parent); // TODO necessary? If a page-sequence is empty (e.g., contains a single // empty fo:block), should the block still be added to the structure // tree? This is not being done for descendant empty elements... if (addKid) { parent.addKid(structElem); } + String nodeName = node.getLocalName(); if (nodeName.equals("external-graphic") || nodeName.equals("instream-foreign-object")) { Node altTextNode = node.getAttributes().getNamedItemNS( ExtensionElementMapping.URI, "alt-text"); diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java index 5d20bbd9f..a4ba08911 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java @@ -243,7 +243,8 @@ public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConf this.pdfDoc = pdfUtil.setupPDFDocument(stream); if (accessEnabled) { pdfDoc.getRoot().makeTagged(); - logicalStructureHandler = new PDFLogicalStructureHandler(pdfDoc); + logicalStructureHandler = new PDFLogicalStructureHandler(pdfDoc, + userAgent.getEventBroadcaster()); } } diff --git a/status.xml b/status.xml index f7c7fc9b2..853fbdf16 100644 --- a/status.xml +++ b/status.xml @@ -58,13 +58,16 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> <release version="FOP Trunk" date="TBD"> + <action context="Renderers" dev="VH" type="add"> + Added possibility to customize PDF tagging via the ‘role’ property. + </action> <action context="Renderers" dev="CB" type="fix" fixes-bug="48237" due-to="Peter Hancock"> Bugfix: AFP Renderer: Respect image color settings for svg </action> <action context="Renderers" dev="CB" type="fix" fixes-bug="48376" due-to="Venkat Reddy"> Bugfix: AFP Renderer: Page Overlays not generated when using Intermediate Format </action> - <action context="Renderers" dev="CB" type="fix" fixes-bug="48456"> + <action context="Renderers" dev="CB" type="fix" fixes-bug="48456"> Bugfix: AFP Renderer: Underline is incorrectly placed when reference-orientation != 0 </action> <action context="Renderers" dev="CB" type="fix" fixes-bug="48453"> diff --git a/test/accessibility/README b/test/accessibility/README index cbe2879e1..391d39055 100644 --- a/test/accessibility/README +++ b/test/accessibility/README @@ -1,5 +1,5 @@ -his directory contains sample FO files for testing the accessibility features of -FOP. +This directory contains sample FO files for testing the accessibility features +of FOP. To every FO file in this directory correspond two PDF files in the pdf/ sub-directory: one generated by the painter, one by the renderer. For example, diff --git a/test/accessibility/complete.fo b/test/accessibility/complete.fo index 03c57b212..81df372b5 100644 --- a/test/accessibility/complete.fo +++ b/test/accessibility/complete.fo @@ -36,10 +36,12 @@ <fo:flow flow-name="xsl-region-body" hyphenate="true" text-align="justify"> <fo:block>(There’s another page sequence <fo:wrapper color="blue"><fo:basic-link internal-destination="second">below</fo:basic-link></fo:wrapper>.)</fo:block> - <fo:block>Apache FOP (Formatting Objects Processor) is a print formatter driven by XSL - formatting objects (XSL-FO) and an output independent formatter<fo:footnote><fo:inline - baseline-shift="super" font-size="70%">1</fo:inline><fo:footnote-body><fo:block>See the - <fo:wrapper color="blue"><fo:basic-link + <fo:block font-family="sans-serif" font-weight="bold" space-before="1em" space-after="0.2em" + role="H1"><fo:block>About Apache FOP</fo:block></fo:block> + <fo:block>It is a print formatter driven by XSL formatting objects (XSL-FO) and an output + independent formatter<fo:footnote><fo:inline baseline-shift="super" + font-size="70%">1</fo:inline><fo:footnote-body><fo:block>See the <fo:wrapper + color="blue"><fo:basic-link external-destination="http://xmlgraphics.apache.org/fop/">FOP website</fo:basic-link></fo:wrapper> for more information</fo:block></fo:footnote-body></fo:footnote>. FOP has a nice logo: diff --git a/test/accessibility/pdf/complete_painter_orig.pdf b/test/accessibility/pdf/complete_painter_orig.pdf Binary files differindex 856e8ca92..caf7a41f8 100644 --- a/test/accessibility/pdf/complete_painter_orig.pdf +++ b/test/accessibility/pdf/complete_painter_orig.pdf diff --git a/test/accessibility/pdf/complete_renderer_orig.pdf b/test/accessibility/pdf/complete_renderer_orig.pdf Binary files differindex bcca16076..e7e4ed6c1 100644 --- a/test/accessibility/pdf/complete_renderer_orig.pdf +++ b/test/accessibility/pdf/complete_renderer_orig.pdf diff --git a/test/accessibility/pdf/role_non-standard_painter_orig.pdf b/test/accessibility/pdf/role_non-standard_painter_orig.pdf Binary files differnew file mode 100644 index 000000000..f8b1c9d2c --- /dev/null +++ b/test/accessibility/pdf/role_non-standard_painter_orig.pdf diff --git a/test/accessibility/pdf/role_non-standard_renderer_orig.pdf b/test/accessibility/pdf/role_non-standard_renderer_orig.pdf Binary files differnew file mode 100644 index 000000000..1700d7c03 --- /dev/null +++ b/test/accessibility/pdf/role_non-standard_renderer_orig.pdf diff --git a/test/accessibility/pdf/role_painter_orig.pdf b/test/accessibility/pdf/role_painter_orig.pdf Binary files differnew file mode 100644 index 000000000..1eaaf1a9d --- /dev/null +++ b/test/accessibility/pdf/role_painter_orig.pdf diff --git a/test/accessibility/pdf/role_renderer_orig.pdf b/test/accessibility/pdf/role_renderer_orig.pdf Binary files differnew file mode 100644 index 000000000..fc8e002a8 --- /dev/null +++ b/test/accessibility/pdf/role_renderer_orig.pdf diff --git a/test/accessibility/role.fo b/test/accessibility/role.fo new file mode 100644 index 000000000..e284cde9c --- /dev/null +++ b/test/accessibility/role.fo @@ -0,0 +1,125 @@ +<?xml version="1.0"?> +<!-- + 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$ --> +<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="220pt" page-width="320pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page" language="en" country="GB"> + <fo:flow flow-name="xsl-region-body" hyphenate="true" font-family="sans-serif"> + <fo:block role="H1" font-weight="bold" font-size="150%" + space-before.minimum="1.5em" + space-before.optimum="2em" + space-before.maximum="3em" + space-before.precedence="1000" + space-after.minimum="0.2em" + space-after.optimum="0.2em" + space-after.maximum="0.5em" + space-after.precedence="1000">Title 1: To Start With</fo:block> + <fo:block role="H2" font-weight="bold" font-size="120%" + space-before.minimum="1.2em" + space-before.optimum="1.5em" + space-before.maximum="2em" + space-before.precedence="900" + space-after.minimum="0.2em" + space-after.optimum="0.2em" + space-after.maximum="0.5em" + space-after.precedence="900">Title 2: A Sub-Title</fo:block> + <fo:block text-align="justify">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 that reads a formatting object (FO) tree and renders the resulting pages to a + specified output.</fo:block> + <fo:block role="H2" font-weight="bold" font-size="120%" + space-before.minimum="1.2em" + space-before.optimum="1.5em" + space-before.maximum="2em" + space-before.precedence="900" + space-after.minimum="0.2em" + space-after.optimum="0.2em" + space-after.maximum="0.5em" + space-after.precedence="900">Title 2: Another Sub-Title</fo:block> + <fo:block text-align="justify">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 that reads a formatting object (FO) tree and renders the resulting pages to a + specified output.</fo:block> + <fo:block role="H1" font-weight="bold" font-size="150%" + space-before.minimum="1.5em" + space-before.optimum="2em" + space-before.maximum="3em" + space-before.precedence="1000" + space-after.minimum="0.2em" + space-after.optimum="0.2em" + space-after.maximum="0.5em" + space-after.precedence="1000">Title 1: Second Title</fo:block> + <fo:block role="H2" font-weight="bold" font-size="120%" + space-before.minimum="1.2em" + space-before.optimum="1.5em" + space-before.maximum="2em" + space-before.precedence="900" + space-after.minimum="0.2em" + space-after.optimum="0.2em" + space-after.maximum="0.5em" + space-after.precedence="900">Title 2: A Sample Table</fo:block> + <fo:block>See data below:</fo:block> + <fo:table table-layout="fixed" width="70%" start-indent="15%" border="0.5pt solid black"> + <fo:table-header start-indent="0" font-weight="bold"> + <fo:table-row> + <fo:table-cell border="0.5pt solid black" padding="2pt"> + <fo:block>Header 1</fo:block> + </fo:table-cell> + <fo:table-cell border="0.5pt solid black" padding="2pt"> + <fo:block>Header 2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-header> + <fo:table-footer start-indent="0" font-weight="bold"> + <fo:table-row> + <fo:table-cell border="0.5pt solid black" padding="2pt"> + <fo:block>Footer 1</fo:block> + </fo:table-cell> + <fo:table-cell border="0.5pt solid black" padding="2pt"> + <fo:block>Footer 2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-footer> + <fo:table-body start-indent="0"> + <fo:table-row> + <fo:table-cell border="0.5pt solid black" padding="2pt"> + <fo:block>Cell 1.1</fo:block> + </fo:table-cell> + <fo:table-cell border="0.5pt solid black" padding="2pt"> + <fo:block>Cell 1.2</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row> + <fo:table-cell border="0.5pt solid black" padding="2pt"> + <fo:block>Cell 2.1</fo:block> + </fo:table-cell> + <fo:table-cell border="0.5pt solid black" padding="2pt"> + <fo:block>Cell 2.2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + <fo:block text-align="justify" space-before="0.5em">That’s all folks.</fo:block> + </fo:flow> + </fo:page-sequence> +</fo:root> diff --git a/test/accessibility/role_non-standard.fo b/test/accessibility/role_non-standard.fo new file mode 100644 index 000000000..b6641aa2b --- /dev/null +++ b/test/accessibility/role_non-standard.fo @@ -0,0 +1,125 @@ +<?xml version="1.0"?> +<!-- + 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$ --> +<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="220pt" page-width="320pt" margin="10pt"> + <fo:region-body/> + </fo:simple-page-master> + </fo:layout-master-set> + <fo:page-sequence master-reference="page" language="en" country="GB"> + <fo:flow flow-name="xsl-region-body" hyphenate="true" font-family="sans-serif"> + <fo:block role="H1" font-weight="bold" font-size="150%" + space-before.minimum="1.5em" + space-before.optimum="2em" + space-before.maximum="3em" + space-before.precedence="1000" + space-after.minimum="0.2em" + space-after.optimum="0.2em" + space-after.maximum="0.5em" + space-after.precedence="1000">Title 1: To Start With</fo:block> + <fo:block role="Header2" font-weight="bold" font-size="120%" + space-before.minimum="1.2em" + space-before.optimum="1.5em" + space-before.maximum="2em" + space-before.precedence="900" + space-after.minimum="0.2em" + space-after.optimum="0.2em" + space-after.maximum="0.5em" + space-after.precedence="900">A Sub-Title With a Non-Standard Role</fo:block> + <fo:block text-align="justify">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 that reads a formatting object (FO) tree and renders the resulting pages to a + specified output.</fo:block> + <fo:block role="H2" font-weight="bold" font-size="120%" + space-before.minimum="1.2em" + space-before.optimum="1.5em" + space-before.maximum="2em" + space-before.precedence="900" + space-after.minimum="0.2em" + space-after.optimum="0.2em" + space-after.maximum="0.5em" + space-after.precedence="900">Title 2: Another Sub-Title</fo:block> + <fo:block text-align="justify">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 that reads a formatting object (FO) tree and renders the resulting pages to a + specified output.</fo:block> + <fo:block role="H1" font-weight="bold" font-size="150%" + space-before.minimum="1.5em" + space-before.optimum="2em" + space-before.maximum="3em" + space-before.precedence="1000" + space-after.minimum="0.2em" + space-after.optimum="0.2em" + space-after.maximum="0.5em" + space-after.precedence="1000">Title 1: Second Title</fo:block> + <fo:block role="H2" font-weight="bold" font-size="120%" + space-before.minimum="1.2em" + space-before.optimum="1.5em" + space-before.maximum="2em" + space-before.precedence="900" + space-after.minimum="0.2em" + space-after.optimum="0.2em" + space-after.maximum="0.5em" + space-after.precedence="900">Title 2: A Sample Table</fo:block> + <fo:block>See data below:</fo:block> + <fo:table table-layout="fixed" width="70%" start-indent="15%" border="0.5pt solid black"> + <fo:table-header start-indent="0" font-weight="bold" role="TableHeader"> + <fo:table-row> + <fo:table-cell border="0.5pt solid black" padding="2pt"> + <fo:block>Header 1</fo:block> + </fo:table-cell> + <fo:table-cell border="0.5pt solid black" padding="2pt"> + <fo:block>Header 2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-header> + <fo:table-footer start-indent="0" font-weight="bold"> + <fo:table-row> + <fo:table-cell border="0.5pt solid black" padding="2pt"> + <fo:block>Footer 1</fo:block> + </fo:table-cell> + <fo:table-cell border="0.5pt solid black" padding="2pt"> + <fo:block>Footer 2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-footer> + <fo:table-body start-indent="0"> + <fo:table-row> + <fo:table-cell border="0.5pt solid black" padding="2pt"> + <fo:block>Cell 1.1</fo:block> + </fo:table-cell> + <fo:table-cell border="0.5pt solid black" padding="2pt"> + <fo:block>Cell 1.2</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row> + <fo:table-cell border="0.5pt solid black" padding="2pt"> + <fo:block>Cell 2.1</fo:block> + </fo:table-cell> + <fo:table-cell border="0.5pt solid black" padding="2pt"> + <fo:block>Cell 2.2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + <fo:block text-align="justify" space-before="0.5em">That’s all folks.</fo:block> + </fo:flow> + </fo:page-sequence> +</fo:root> |