From 91cdef3c3337a3e2537be2136a98eb7a7b46cebe Mon Sep 17 00:00:00 2001 From: Vincent Hennebert Date: Wed, 13 Jan 2010 17:05:59 +0000 Subject: [PATCH] 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 --- .../content/xdocs/trunk/accessibility.xml | 27 ++- .../apache/fop/accessibility/reduceFOTree.xsl | 4 +- .../apache/fop/render/pdf/FOToPDFRoleMap.java | 180 +++++++++++++----- .../fop/render/pdf/PDFDocumentHandler.java | 3 +- .../fop/render/pdf/PDFEventProducer.java | 11 ++ .../fop/render/pdf/PDFEventProducer.xml | 1 + .../pdf/PDFLogicalStructureHandler.java | 10 +- .../apache/fop/render/pdf/PDFRenderer.java | 3 +- status.xml | 5 +- test/accessibility/README | 4 +- test/accessibility/complete.fo | 10 +- .../pdf/complete_painter_orig.pdf | Bin 96863 -> 96966 bytes .../pdf/complete_renderer_orig.pdf | Bin 96726 -> 96880 bytes .../pdf/role_non-standard_painter_orig.pdf | Bin 0 -> 18938 bytes .../pdf/role_non-standard_renderer_orig.pdf | Bin 0 -> 18849 bytes test/accessibility/pdf/role_painter_orig.pdf | Bin 0 -> 18924 bytes test/accessibility/pdf/role_renderer_orig.pdf | Bin 0 -> 18835 bytes test/accessibility/role.fo | 125 ++++++++++++ test/accessibility/role_non-standard.fo | 125 ++++++++++++ 19 files changed, 443 insertions(+), 65 deletions(-) create mode 100644 test/accessibility/pdf/role_non-standard_painter_orig.pdf create mode 100644 test/accessibility/pdf/role_non-standard_renderer_orig.pdf create mode 100644 test/accessibility/pdf/role_painter_orig.pdf create mode 100644 test/accessibility/pdf/role_renderer_orig.pdf create mode 100644 test/accessibility/role.fo create mode 100644 test/accessibility/role_non-standard.fo 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 @@ +
+ Customized Tagging +

The PDF Reference 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.

+

FOP provides a default mapping of Formatting Objects to elements from that standard set. + For example, fo:page-sequence is mapped to ‘Part’, fo:block is + mapped to ‘P’, fo:list-block to ‘L’, etc.

+

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 role XSL-FO property:

+ ... +<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> +... +

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.

+
Testing

@@ -119,11 +139,6 @@ SVG graphics (or images in general) are treated as a single figure. Text contained in SVGs is not accessible. It's only possible to work with fox:alt-text. -

  • - 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. -
  • The side regions (region-before, region-after etc.) are currently not specially identified. Screen readers may read their content at page changes. @@ -140,7 +155,7 @@
  • US Government - Website on Section 508
  • Wikipedia on Accessibility in general
  • Wikipedia on Accessibility in PDF
  • -
  • +
  • PDF Reference 1.4 (look up chapters 9.7 "Tagged PDF" and 9.8 "Accessibility Support")
  • 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 @@ - - + + 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 @@ {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. + ‘{type}’ is not a standard structure type defined by the PDF Reference. Falling back to ‘{fallback}’. 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. --> + + Added possibility to customize PDF tagging via the ‘role’ property. + Bugfix: AFP Renderer: Respect image color settings for svg Bugfix: AFP Renderer: Page Overlays not generated when using Intermediate Format - + Bugfix: AFP Renderer: Underline is incorrectly placed when reference-orientation != 0 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 @@ (There’s another page sequence below.) - Apache FOP (Formatting Objects Processor) is a print formatter driven by XSL - formatting objects (XSL-FO) and an output independent formatter1See the - About Apache FOP + It is a print formatter driven by XSL formatting objects (XSL-FO) and an output + independent formatter1See the FOP website for more information. FOP has a nice logo: diff --git a/test/accessibility/pdf/complete_painter_orig.pdf b/test/accessibility/pdf/complete_painter_orig.pdf index 856e8ca92876e1f684c3db2b74381c70f3a2a14f..caf7a41f82189ec3ac7f42e5887d893da654e580 100644 GIT binary patch delta 8661 zcmb_hYiu3YamHLl6?r9!VknEUV@XTOwDqF6XWvUn6e&`a^)e~yVLeDwq(n)iDAJ}W zztWa*P$WQ$#&$2#`C%tWfjCGLq;<*$Mjv+EqD`A0G2FUAWT%Gh#w~2MP3)qI`!Je* zbI#t&ySpmV0_6{$-8nPo%*^@bvFE<|uS>skW9gGS>gQ&!PG8Lw9NFdP3|@*Q)^DyMx`BT4Y%?T_8KM&zIsGfdr%+)!o`~J~$m&UEW{(;g5KaKcPiW=_QKWA-*kP~iKK@eJ-CLT<`kEUPmpPiV_ zNL-kiy)rsCH$I!@JU=_}P+RGP>udRyrKEbtr}cE`Y>Yk3B6|4)O#xtALJtp@169x4__qK1TLHKYST zdTArM+IZefblWDaZOT;fmsL&TjHzZ5t2~&1^Np##G1WKP1t#tSzqR8;cXq=@S zn?Kx0?Y#01S{B;It;#l&xeRrl>q~`c>kdaqZn3 z>DCh_bgBcxET4)DEDm*LM?bQIvcHv|q}04e`DYt(0x)J3|MCf1Ht!^sRK~=7q%b)N zl^gYmTgpv5;hGauNfatKaa)rAm6y2HOZbt?^}1#pwiZOB97OM@GXHIY#&D(jy3 z1pD1^>C1)C=BGW{RQvP{mi9Lr=q%e5l2o@Yf# zj9MzmPXV5cqeHBy_*I|I6k_$f9nc0sp&kfn3x-dIq>wi7wz&|wd<|6Y$G<`p^7e@4 z!18hgPS*?}PadZYyf&sEZZ&RqjdJBYXsj-$5pzO8#7!MEhNZr74%;9_Kih#_V}4*C z*7|7&eHqVB@1U*qT3X!DKQ;+#`TIL)N8xV84Lhl^;3)ppT}TnDcG9u}V&|Jjs96>} zd=FOnmtAzH%xuL{b$6RxK00s47YzA{yJ<^PP}$;e&;DM3P!8L2_=%8izdbwYnMp0e zr#s2D?wOez7ySm3UPhh|T4xf7J3fD<6B^#WgNpo4C*1*Mx_40{_wPo6dhR&Y795v9 zx0`wsBm9aHqX(#QiRFa+WJsS7tEdZdU!S5nKGFr#WXaV|C2(a=ed5FXTo*Y!h3NvM z#U~9JGvK#XU9_&LV!3v%d4uu1tQ)8Ma2M5WGw6p&-BWYcCUiR1p_z*_n~jmm*M?uT z%<_Cn#D3I8O|`B$W;f*D?uNxXyQ!An?WR6n*-N!6^5qGk0a4U`1~{y|Uq?A=ATo!+BGALxN-XD>t_yN`-%3?|E> zCNeyiAM3>mS|=Ti<@uOj>7iTszj|pqsz%#htawEBH=kqePv}l zRXM{qdLeVR4_e43w^ncBC2^_`kpHZYcEVuVhpk-x_95W+$$b#pK0-B(CViE+(u?rd z_ESf}3uLDjNFZ)3{`3JF!1J(x9FYsqOO$HN;}w`k47&`_i*NtP43D2Q)ZaFm#c-(O`7T+liIYyS8MHStqOZ2X6(5anMSz(U%d zKxfoM??3~GmmGmTda*LybZ#_Zn^=SnH{_F|b%kQ5grS)q{Pn%?+ zY@cUN(3+1|dK3*SlvJ0yPf6%QcmB6i*!YQ4v=-_E^;D!9&i}juo})n2004;i&J!G%VI?`U2KAna=)r<#mi13 zuj!i9cbZxu{nb-Y?@vzCCR3B*m~Wg$x<=I3aNikfZA$Cugj!K$>nf?$`mNK{!Y_eU z)?L2JG^>@ZJ+2wTmMBWg$zD8~sWa5Jwz9NTp>m%pW$5e>`5zk{n;Pd2PSGv3iNlq{ z-x{J0Q&esY(SFITH4Vzv^OYT=-yEV(@aKk6RziMpm>z_cQ^NrD(fa^X)RWr!>U4~j zoWF1%R1}j7Ff0KfGGH^;j6ei+WCedXM0G`FIyj{w-Zugf*`Gf%LMw|(X=BjfbN3|T z_~j9@f$N`*=$s+WP9?RVw5ko=vvr=0V!1ovQ1{u2Jk>*`r=5U8vEh z=rH1EN2wEn?~Lj_bVhz;3=$|E#roETmAw!{^HuHy?x*JBy#%ViQ+*F=C_k2*!(e*yZX0;WlLQK>YK z!8{1aO)dQ03&2#K*@OX@5C&Qe#DN|W2rb-l5ncvrRxfk(DWi>;q+9qwAxmyvt5Thl zN-m3(%O8xQbAM0xJ~=7f8G5%%bcPR2kk(N{=$T8HMrN*SOhL$WJ-lRscHWU{IR1wZ z7=8qt1y`R#i#PyaYvGS3#9l#R)eNB1%*Q6NZFWXOI(ty36=B zfn7xm{g8lv{@kEp{E=FioxV`a?A}X}hkEfKAcDSSQL1%?S{#DH>$u6D~yyV^>;_49%0$ zZ`vO zF9IcU9JxZsFuHOZlc9NX$&;n!fENKCdD&3v#GWrVEIr)uUH@z_=BG+@|;wvNUUufr*3FYQA!x!a`$@9usm|wKS3*<^7 zE$l_oc4cTW?xHg^-KU3ZS4$aMAa@uUTA0fV zksry;M}{wU!uc#QuqA({8H1agap2^SDR8BJWn{gZtmjt}+HN1CPJ!*py>)7n!1pqsv7wABH+E@0WYN5AkOM0yi@9PxsZs$n%(^=8kwUVYgvj(6 zS`&qB&hRL9@_~V_pxPH297ta(7m+d0o!cbH z7soi1FT;#7k;=l|M^pX()J{0f|PKWOq>Pim9ccI8_uOUng8YJF#P%?x_kNv7;8FDhaCCadHtE zqc&#K2%wOQ(%A9i`JC2Hm1GJHV@)MRMj%Xo(EN9kj`>|7EEA}1Gjp@+hdT`@u<|0wcE zK7oc_kjqbDun)geANJ328nK8xQui|t1z9vjEc7(uapaAsx>zktXs zQ9J+SQEC|J0o0Y<)93oZo;`a#ug~rARZrmT4g5ZPZ=cs`?fkhc!*av%;N0l!+#|E& S7mBePL~*gTb#H%P@xK9?<+&pO delta 8524 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 JM+bA6{{_=bnq~k1 delta 8291 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 E1qnAG{Qv*} literal 0 HcmV?d00001 diff --git a/test/accessibility/pdf/role_non-standard_renderer_orig.pdf b/test/accessibility/pdf/role_non-standard_renderer_orig.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1700d7c03c546279ba4fbd359eaaf45313099fbe GIT binary patch literal 18849 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 Fe*xpF0#^V4 literal 0 HcmV?d00001 diff --git a/test/accessibility/pdf/role_painter_orig.pdf b/test/accessibility/pdf/role_painter_orig.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1eaaf1a9dcba356b55fbc06b3b2906444d4fab17 GIT binary patch literal 18924 zcmeG^33yXg)-Ordw1v`^vcscLXn`#6WiM@^Om| zh-``=g8~YU4vV-WiVFjR0`5~}5Ku;O6j4!`bMJduUeY#!Z)QH`|0ka|_nvp(Ip?13 zo^$UFnN>w45=yERXKvg6)YD=mDJLCuv&Ff&Vwv8>7(EUbnN{F4ni?6hq_T>f#JJoR zhn=jMG@kUhn(a;5Vp)~TVQw}t;Rj-b@OF{W!;o1;IkcRT%PI6x(sJ$8Y;k_Rn6aA? zeU*<7QZ}Ackg{^d-r#8@l{$D(O~OF82iUWT2_mty++ueKlL^9R_qeLZ6q1vtOeJFv z6G9@Mh#@F~Fq+)XikcDw0iUvBJ?Vx)sO|s!c!Ch1-usf$Dw6cWBWiUsIb9xt5LCfv zg_&`ipuGs%))tQw!7oBPt*!~Rg;A*O0tTVo6SW)I_6R(NZI4E6v(0XXF^FfU*=9!V z1JJ%_ZZiXIQ8~01&$Tcu(Eb40gRRXr3$%ZNcAAYbx(OmG5y3r-sS(<8XeYW1)p}^> z5=2~LLqNMOpzUE=flq?aJDl@emWDKqsQaSk;z(GTBH`nBt-)CeZmg# zjqJD)Ku?P3`D8~HG4;k~tA|8FH94$~W*6xOXJkl8un}MPiver}@G+vAsb^e_9Y{?A zE3?=eK;3q;#e{q^a387q!7B(4S~ROmrpEh+ag0 zVi1uvOl&1~ z5YG~Oh!=_1h&PFMiT8-(#3w`>afbMsxJdj+ToDKav4SK)s-Tx(fFM&aTtEx7f_y=- zpj=Qbm?D@ZXb{*1&4LAjI|WMxD+Fr=8wFbhe-b<|cunxO;Hcmu!70Ic!9N7Q2t~p~ zVVba?aEMSQ)CvoPf+9BE}Iw*Qy)F!$h`Z+2lDm99Xl0=P+Dvg>L zWr~^;b!*hJsI^f~M(vI|5cPi4si=!lzeguU_l+JNofBOaJvq7|x+QvX^s4AB(YvDG zh&~>DCi=&in3(jKp)s16(wHeRvtw?KSr+q1%+8osV~)n0j=2;Y8`~>(cx+y5WvnsQ z6T3KeP3%*#uf!gUJrny=TteJ{I6AH*Zfcx8ZeiT2xNUJS#~q718+Ro>IX*K!C%!V? z96v99dHm-1eep-)&%|F5cM}g4=ZOvC+2T9ItHnFSZ-_q?f1i+$kddHEn2=yexIJNY z!ZQhPC7eq5IWZ-1SfW00dSY|peTh#bzMA+^;`d2ONkfuGCrwTAB;A*^HR<)F&y#-Y zlG;VurL2p&%WYlOb=lqJSeI|Q#&^x^TF~{TuJgOD>iS&QBV8{f$0rX-)+Za2Z%tm8 z{Cx7s$a`i+uhEk#HI{MDNZq`EJ}Gi<@J=)siM?Dsrpn?>Yb^Z zQ{PBElNOUUG_5RccG}Xkr_&CnUF@FHUD^rP)b>Ex&KHm3G-%I`a_Z!pC*>6q1*ZW=Q zpWc6T|JnUl_J6tm`2nc|@&{N3tQ_#lfUn5zWC3X}`l>JEdd&7joRKpsFts8b^xNx|7 zxMlbw!;g-L9-$jyAF*k~NlBulKr&adU2;mAE-jZXlS7s{P zT6S@)X6!9v4~$D3S2J$yxG&0wmAlIKRR}A_RyG;g?_VIfviORCd2P;3T8d^1{ z>V*k06RIYxoA6~dRlT74U`=Yx%$jXAKN<=R%MG7Q%$nFdasQ;QlcrDFI_Yw4QSFM_ zw#l-|w@iL_O7AI_DSM~JPMtJ$%hXHLil;p^?aXx5^u^Op%osYOb;jE_^}fk^(@QhE z&NR+^ZdUZH+F9FX{c5ZychRIbJ#6~gJled{e4fc;RxoGl^XgaBpKHi# zc(CDo%Ua8KvrA`hn0>javgwJYtJYfUPFtL9mhE|aioMBxz|r5)>Nx5g z?p*9_o0Bu=p*a^_<6K+Z0{0B}UQZe%Q-_+fn(t~pH8+3my175KOlo|l&dy8EPlB8;kMP~tM{%MyypHjzpiaudwgBtx}EF$uD^Hvc%cP-g1*gbFe#XXIC+V)P_d-VCS&+p$ia^J2Oq%S=2;=mWz zz101s&=okUq4uI z@Rhgn-g@!voVTBUNBhp6ch&FiKBPLd>o2Om>^iJIy!(je$lmvK@9jI9d-UaFqmI4y ze$o4Heo*$oyT`{LKYC)~i4RXsKiT%7`NMM`SwH&j}x|(wD2w4mi8@9DVM^^Cjos`)b-( zXTElRedWU9zjyol`fswn`SZ7R@lt1jhRCVd|A8kKg zxxD13UOzqgv-anMztsM6_DajIvA?eVE&I29zmNO<)2p_tS5e`?l@weFqUK7FX|giC zzR>7q%p|Hxs%Lm>6jX|EwGv6n4D*}}DXU;SMzhgl6a%EDxz2-ulPk(mpDSTha)brd zIvl;+QLT{EH8CEtj%l#i^D@4D;gt;1V$RE`RaM9C73U z^2OrZ)|^(G(*^{|R-4uC&S}ldFhcRftu3TM$-})A#u;MdyK6TyL*rqLlIOpE{hXqe=ISx$%n|^is^9$1s$}k6?@(?&0ep7IIjGntXddUSMkjDC59J)*$ibC1gX-)K1RFF6jLG|! z!)0(dtYKyoJeqyqYy4s8@`kl53anSKTBLZNl|#qpDBz-b87}Mwp^mH6cs-Y*k*krE zg8f398_?_Q3wt<8A>W6QfnPqiS8CxQ>-T=2rtk}XpGJK-DM4Q}EhkMj@f3Xb{Uv6eOi34fWhx7!#$EDs(zI?3rjtgN>Y) zWw3ax3`ymX1_xQ=F}gftt;N%rJ%coi6&D-C#T9zMPy6swLHLzYWe^30MyjHK0wt#c zDbP8P075vEV1j)7RX+4|AbOZ49fVw^lB#JHgc_xaMb3FlHpoe-ld9Ef4Vi^DnRtNd zStSma&FJx<8kF~>vTinG^0@gx*o-nUZnwiVJ)8f)5;V}rf9!Nw?4FKhrU)}Lja(|H z)u0&ICBcfRXIX|lv22o7N#$CFg3L0zEOQxqAf#?yU~h6wd0>~r!A{$U1PqUxv=1~r z3*MBJRN@)?phmm7qvyCs zsS36h&DdU)UI@#Bx5v|s#5agl4xXxaB$zL&82>2PxMX-^Kvldx?7Ns@pOpvmG%_8{ zRvl)x6s3^TXu295xFnjdi*duQ60$6(v4L@u9tUZJjU~opskcCy!zx(Hrxy@MG=T&m zPKCx13Phq)X~Eak3YH`rs!$-YJ76xZ@Zm%oNTr={La8-Uxf-Sgw#w4@uZbtRa8uJl zzM%#WR46%(`5Xz1!sp^QOhBP{D_48E(y63cq$`brTUc)Nm;y^Dte_Lb?W7m}vk8>d zS2J$dmW4G3PAO1c?<)nWz_n1Xf-zf+g^pHo8cGQikPSdaFatf&yByAT9~4>{#@y}` zgUe!T_d%5rqK1dWc?iN?1E(`44-0jZa?F;o&J7PRWry8^(sU9hGq@P>RyFv91*JC% zN~!b$am|8&T7}#PL$nYKst1J+h=hQE(|E}f2^kB{s8H?%i4}W_L$jF}xGw@KxG#2y z63>KGvZWa;}BFV)3nM_!7mP=`5%@9%lFDxLu zys#bbrIjc-gY-th<(=2He)#iTUZU7eo~wm)N`bOaB^TIzd2S73f>Q{xoisFHdE#Yj z?JrMqIG94qlUl_kZ2skmtTEc0kX0Lub=D4-+;ABbMROLS)p99D4XpWSV*qM=tD_}{ zTU*&E<1Y=A8Yv`Q6bPJBu|)$Mp#cQ2sYn|M9c12Cs2^ylhTlXZ*av7hYD>UdaHEl| z72BcO7$crG170^{aEqA5#$xs&WUvT%2Q)E1PECoDS zBnyrnOom5{>vTLd-@7)iw7jTTYOG)bhy~K(#2g^}0CD6E&hRhW+tD~Slp{85IN zrGlLX*Gm-Wm=|SAAuENOgOL$y=%575He?4UQ9QHF?mIE9cIHyG|)UlEQgozUxVe)9a;_-c$5mM zyuH8^=)GRwk2uJ9W#Q9Qr4dv4Wzd;bYAWU^2egL&^W;@#V&~q<^o$gsr}V7bnhO!iE?%1v>-n ztJDn(LRIvH-w|$ZK<&JIA=t`;i$b$V-?!DMEjy}u^x73|0_0) zsg5>{@xCi>(^!Re70~olv_kFM3-+DEEAd9Jf8Vyf6ZGJV{r{1DTLT>YO{ZzvO&X!x zsdreL+}>lajt>A-XrubSOqXaOx5WzxB(L@!E3lq&9i$|M4y!q0 zdVX@=J6!1C#tlDzaWumW6k^#p3!DW{gG&qOlma_4e6fcWGte(lxcg#!4`=z-!;Y`j z(SVr2SpDZS6-HN6nZ4ctw96^V~e5ZrrthQ$7Y zAmv7oXcl9aj490a5-K;sHZz>=U@ilti}v9-J<70#SSgoKBvvs#zJjYKSP9s}(XV?< zHE=g=8cYH1k;%$zAf7_*TMsgWAB>PQkhrW4R}KDg0*jOT?E?Dgf{zWqw7jt)P|NI@ zm3Pi)F5}2)*go-b8GD$89%G@6Z?=J2q)8Q)7S>JR-2G7pp=K4t zk}QT>YY0|D%8DGOW^{uMOVTfPU+mVT$95~5xWo}bMR#e5yf-^I_hK5V}5YNgrH92 zpw8zvqNr?OV=l?^hcF{-9G7@e;3JJF@ES@v7BN>|q+G5aIOl5#sw`6+vOuN#BV~{d zaZKa0A5oxcpM9LG@UdM>5JEL7dkY8z91;7Wah8tAuMMdD~$UmEw^3lHW*$Ooc{IJf*M{+vh*j z4e`~au-Ldb#Y&SCMnpzJg~nnWW5QB26gtfFIH?6%i2}PRslbxtYa$|V^%@Hs>AZTy z#!tdEpRw@Avqy&JA$Ue%33_dX&wi*oDk5@6FZ+Ss z7?G{utcI`B$Xu0MBX}xRa^*m%#p5TD%Oucc*~@)A7BMI+HcloiQ`h1@IDO+2jBMTX zS|pEsyl(QbMYLdg*$-SVBT^}wQt~NAUgJKMCCa@ZUf0KhNzR~VQ z6`4h4qkRjg!MQ%o_R&vI@N)(3vlThFUDE1e>fuhBnij*wLheJVRVs)S^&|_U6mnF` zqYr8K!2lWpqv1%IKMs1ZB^?Z-RIrYrj}M<*p+MW2JQ$@=qHrDrQ=yFp9t_^q2E$;} z3@wbjag;)XuDS-nwD5D6V32d@C&CbZB_BcQM3Z?^#;RKp?*Xw-~xB>IHf!kpBC+r1<}x=WjqLme%j`P zd0a+|m2u&JOR2^(pFy!shIezpfS^W@;r(AAhTBC@E@-qx1%<^0dM&M_iV78ad2vZG m{9jU{EYK@88eKjaeh6M9+~~)EIKomI6|ECzW)@eLi2n({CLCP= literal 0 HcmV?d00001 diff --git a/test/accessibility/pdf/role_renderer_orig.pdf b/test/accessibility/pdf/role_renderer_orig.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fc8e002a8ce877914ae8c964e4be1c7596744cf5 GIT binary patch literal 18835 zcmeG^33wDm);%*hCkaOq!VOIzkN|UZ&mEFLGD%1vAt4zE5D+Faon**d%uGl?ybw`= z6-7iYMUX`S1y`3tyb;BN1wjGt4YCL*tGJ4&sO+oio}*_b$-uX}AN&8CkB?Nnu72;; zyXw8F>SR)Xf&>f` z<+eENWcB0;q{r24Z^{zO^e)Ee0brrg!;qPU*|eOJ%PI7uq!r3(S>n7rF=IC)yec1l zQZ|89kg_ty-r#8@l{$D(MZ!S02e8@11d&)$X0bbj-3Y>F_qeLY7LZe>P9tLv6G9@M zh#@F~Fq+)X^6Fv(0Y9ZhdeRMpP}~3W;|W55dhbh0DoN50kEqq%e+avK9wmk;5%{IFk#vq=ZW}6wc4?z2# zxy=l;MP<-lJlDdsK>Gt|53x4eEYSW5+Nn0i=q8A$LZ1s>xs3wQi(d;7K;A0Fa2{z*EeldWp06s=mG4+g#u>+~eU}YA2 z1E||>wjlQ_e4Vca@PL}ET|*;f^Y29JOexXrNGc)v`ynDKC4mr4e-xewe0nR3 zpG+Xns~LEfwR>p8bNoN=KjCud3f-0l5`pzq2GZ2*nv2@t6X?HaLQHfeQiqDj;J6E#8l!Y!bCI@Ho`@;5DSPqh{eQG;(p>GVlA@&FUK8=I~#W;zFT}oe0F?Ayg7be z{POtC@%!SB#Gi@3BJM68Ce9Tb#IwbBh*yhuh~E%@D*iqpAt60MmoPEGl5l&%>V#(! z-by%?@N;5v;_yU$;`GGk#QPGTNPIQ%qr~r%l9GldjY*o8%Oe}w(f6tKbIVvJT$o|*_^y6`SIk}lTW9JQU<5!Q%os$rfg1m zBjrqLOzN=I($v|hOH-dtJ)C;6M{*BkkI6k+d#vm6QjfMYQQFY7(ll$@^0a5uPNe

    NlulQ1hUTgANb6l0Gbb zQu@O5o#~$q77x}At{=Q|@czLUhYTE2K4ig=?L$7!h|kbwG-f=UaWLcZ&|yPshTc7N z&(L$jdJQWbHhmF95$X|^ z5s!>GIx>2sZlrzWrjaKliIRNDT*-FHDQTLtOuA6INBWIyh-{kd0og&>?{bygD&H*s zgi5ByQ46Vk)IaFqw259vf1pTG6f161>{WcH9HC^Ck19V@rKrkPcdPcRep74IF7*!e zdCd^bEX{h&No}gOQoBt1mM&UXpu0`?qVDHxb+#w_+3aseNk%n|+BWK3&afONXLHW! z-1J;y?#A4Eff`wEnHG~xG1@3QqkI?&x_NG8;Z9VUmU9%d-K>=OQK80mpo8%vb2AxsdQ`U z#c`T(w~RY5K5=~Y__gD|C>vhpD%)2sEFV|?VELyLGA7t3?5Q9sN-G|$_^fhR<($eF zCdN#xoVae{msM2Nf~tenDb+Kpw^jdWC@?HHd@?C>QuCz!leVx@!93=_h6ko6$Ps?VI}CWWDL7nO$cZ zXFfM8dREP>ZL@wgRv0%KFV&USt*^Ui(wiPOeQh3NUTHqhvp3AX+*Hx@MAKDkjdiCj&Nj>Tygk|8WIx~-;AnLmb&hZ@ zcDBvQp7YS0i>~pmEpCB(hI_9k6_Tk#&6&-2HJ_TBH+S9KpIRojJlER2)!uq&-tc+% z&O1B5c>W)6j=I@&^Zo^c7TmGm)Ghh9Y`j%)Yu&B;ZyS8uqT9~gKKAw}?-1Y7bjM#7 z$``I!_`{twckWx%f6?uWPTw{5uI-DvEOsqEdH1NhH{26-kL8}j_bTpPbMNm<%uC)` zDqp&4>95O7%ij3|^@r7exO!jxeTSE;mp^)c%>DNJPdqUCfhSjVUon5h=?BXn+`W=q zxn$)J56yh&?N!QE8y*%v-28Cc>ax{)*9=*6|C(RdHm*Isu3+8H_5If0yZ-Vc=0}b_ zI_A+G8~Sfpy5X0{ERTJ-aqPz3n}%*$^?1zVb07b5^W@D3|ET@r)-8RuEZy?k6ZR+C zo~(NEz*f!Ht=sx-TfSYmy?Oijr=~yk-qVFo@7*EUv2kbG&ZW-~&on>t)t_el>BO_+ zpWXkQ_PHH@&iM2CT`9Yk>=x{vxBKFr#yxF&r|v!a{J7`$?;Evm*9+1Yo_KN4i|bzM z@zU~_#V;><`RXh4U%B+E^VJKlHN19u|IGcLygudi4-QN`aQKb!Z@l$p@tdz7%s=?b zTe)w&_;&W&&%dL6XV1IpcXuCB9oqF5)n9fURv+GdL~~^Cd%E}b9nCrV^0Cp!UVFdr z{Wm`-{ovi>6OJD}G3msIC#Rom`_TO1xsR+LefRO)kFR`k`=`;LF8Qq6XRAK%_xYy3 zX8m<%o4W0#Q-!AveNp|zC#OxPzy6#1Z@->d^kveQtIiHQyY(D>?#1)P=imFP_Ny~r zJHNhiVe#L)|9$;8ncw{R+cDoBx;W+HneSZRUH!+h?|Xm$#1G0J_Ft;J^!bmrAFo_q z@>B1hp8Q$+^TA(gemQ%k<=5C>SO1pv+rHn&|NiM!+tsV6@Zd@ct^`qYB}lETRIe{E zx*0Qxs*=Z(n#NowS&9(`!`a@^Yu1X|$BgcQMuTCm2lgn@l=$`sh5d zIHxtc)#kJTL9*3mwY#%hbJLAbJTckOMqpWbo;b&4uFtM2EarwlFE>3Poo!J_9j*o$ zr1v_RoR-nF1V%{Q^XwjDtHkae?8Q(BRgKHy#MvK9%xv-@ayGlH7>(H^W2}sgv3uMy zN=nJnNkrXP=V0OqU+oijYhhT55{hx4F>&Ow6%Vd5MN;L7N{j;d(xUGGp%Mge@b%Q@JJPh&jJ zTa8ZOTpr3fypfGdb_NyfdEo^cG$<@XSh`?@NToibg^the!Q*n%UD&Ea{ZOg#IwD0Q z&mk!V`wQ(sK(C`;*kMTuxiX9l{N?jvr4}BtZtQna3cuiYQPh`{67-9v<)q0bo+D;q z6iLa^KLE+e2C=M!B6D(N<@(Y>QV#DI6zatV2C=MIK~h@MP|v-EF;Ob1LZ_3%7Kny4 z*vQ&UgT-TINGh8&ILK;`(d8j)ES|=!8KhyHxX2(bD%S&k+J~PC!mpGngD5C8QWXUh zC^;2KfzF0}4x*C;6XfHs^r5E%(Ze+9Aml2QR86ZOawt_Sa?WnEKu$`XRIOHP$V{{q z!~;yvEOxkTMvn)Tl)NVub+Z|h$IS=A-ja!NyB)6SS^Ni1e?)&~#`{Pe#PFM5&g-G+-VOot@1d9>`)hGfr?y zh~zxDPYzNZxRgJNRgDin){L(=&N!D3Fgl%9iwW-wwl_glCll0ZrCMZ(YOsIgN1jF_ z%aN8-73>t6vArn05S9mTkEa`nZxE{-JXP;VFke1uS~l4!mz#toZ9$g-TUvbsr+gEYcE5o5B{TOey;6)fe`3y33{ zK!OmbLgNSpBGIX|;OlAyOOg#$D3I74Fc(+n;Y1rqB}_P>)EcQ=4buW!Woi7^#1ma- zQ`5q#uLciPC^?P!90`oV=i)a^K%samS2$hiR8lR{l}5oWEH`>gfu$2x(23$O>4pEO z0VU~Gj2m`YVa<}fM38`dLHw7+%KzL}RFB4Pw50(6x7@NU?gK@*`RvQQ-#*nN3!HDiK91u{$;8n8U^ zvbFHblN`>O(DI~KaS5A$c_OQgHYa4&24kJI-6glP42q&T3(;!16r&o}d{pN{$!>MD zWOHjP8)f{Zfl?!dq>BQ9Q!2J-fDh$nfsT1mrUbH5$ebvi@nB7XR-vdQDHXPsj_e26VGRfcR=*)#m-QfAUgH3C z9odeT8cZ|5fWU+UyU@F4djcVIrsc(SLl~1+G}mD^tV9FNGsJRu8UHm{4&AQhaDhju zkjldaoxO^NcWQjPYP{8MJHE)~Ne0z&J% zwuHdgXwc;+^pup9FxI(@2aapez#_ZJVMeEpvKos$-|n_}0fFSz-eU#UQ?7%Qq`+Y{ zM@-L8&U+;b9o)F#;}b_S%s?TQjkmyAa4lR~K&KSgk>MA6STO^ASi)WZ;(IvDw;pzU zt&Rr7494m|pD8!Gno8~U4!Au5M?}zpb5}UBVGu$rRD6D8fTQ9nSgJ^Te1hO*a2<-w z#225kP~UrhjKu!qB~)gFZDu&#!CVGP7wyAwdX!-eu~IIkNUUOfd<9oeuoAF`qmOk= z)o|6U7N!8#!epg35KjU3TMsgW??1>HNL*Hjs~Uf6z~baSML=I7_}K7E%NrX4walJb zdFPDgGM=o(_KAjZn?uL?8W0NBB0`T05ze*( z(fe()1CHTLghS7Ah=wA3_^d4W?h|Xo-m^I@Cv?vU$<2Ex#~!tLLv|oL;Ve94wk0?M zRFdp`IA#L1T&~AfR@p$ZE`^4$*Pqbb`2q+qR~Xff%1Ur>yB>;EC`JE~Vh19xM9;2= zAdLuu_4;wQD-A{DLzR&aRYg8jjfV2o;a%keClG1?*R2jsC`JBK+l~QTw>q?uOG6j= zP)gpxSa$v3+k86)5i~T6v9=#X10vcrIAjn-Y^{6?h$x0$gF^;U#757j=*>ntw7JMF zAc!D#9UeirpW#~~+mAW;bT~{Dpm7u@;hG#?ir9q+nS(D&h$yBT&`}?Y9`l1ECIodF z2X#Kb5k+MK8*@pPKZF@!@6S=a765f##uTdzc!%qlT!d*v%Lzy%Q=4r5xK3; zMzGa-v9Wa-T-yrHPUwg{(@@B-*OVMJskRA?;5F{V?Bh60Cq9w)UxD^XxKB^6kbd`(2;tzKhcBb`^T z*!W4fCKPNeipV^YGZvOPFVawt#8<^Sow`@p*X)s@c?h0Srv$yW!e>9!9TgF|qnG_a zZ;Z%Ra8|=tX=JX-tr0wxD!FnX)Z+1z$Ym1fvh3wP9*Y>%DK<_fEK}FwKRA8k6O3%# z^jaj3eY|e+u|>3Cdf5+LFC$VZn^N*AM&za(#R!Tqc1Hurw4GuMZzixBfo%=rht2{K`=_8K=)30_$Y-E?h5i@au^5R z88l9XtTPCvM)5BQrqKlBqZC@Wp&v9(DG!+&{Ph!E@I2tMF5KJ+epel4oHooj9V-6$ z{Hf$PJuorb|Kw4%Wj=#qoeb~hvhiPr_kU3suM*4P^S|00rB + + + + + + + + + + + Title 1: To Start With + Title 2: A Sub-Title + 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. + Title 2: Another Sub-Title + 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. + Title 1: Second Title + Title 2: A Sample Table + See data below: + + + + + Header 1 + + + Header 2 + + + + + + + Footer 1 + + + Footer 2 + + + + + + + Cell 1.1 + + + Cell 1.2 + + + + + Cell 2.1 + + + Cell 2.2 + + + + + That’s all folks. + + + 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 @@ + + + + + + + + + + + + Title 1: To Start With + A Sub-Title With a Non-Standard Role + 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. + Title 2: Another Sub-Title + 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. + Title 1: Second Title + Title 2: A Sample Table + See data below: + + + + + Header 1 + + + Header 2 + + + + + + + Footer 1 + + + Footer 2 + + + + + + + Cell 1.1 + + + Cell 1.2 + + + + + Cell 2.1 + + + Cell 2.2 + + + + + That’s all folks. + + + -- 2.39.5