[VOTE] Merge the Temp_Accessibility Branch Back to Trunk

View: New views
12 Messages — Rating Filter:   Alert me  

[VOTE] Merge the Temp_Accessibility Branch Back to Trunk

by Vincent Hennebert-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

Work on PDF accessibility is basically done. There are still some tests
to perform and maybe a few tweaks here and there, but the main
functionality is in place.

So I’d like to start a vote for merging the branch back to the Trunk:
https://svn.eu.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_Accessibility

The vote will last the usual 3 days but, since it’s a non-trivial new
feature, if any committer would like more time to review it, feel free
to say so and we can extend the vote to 1 week.

Attached is the diff between the branch and the Trunk, if this is of any
help.

+1 from me.

Thanks,
Vincent


Property changes on: test/java/org/apache/fop/intermediate/IFParserTestCase.java
___________________________________________________________________
Modified: svn:mergeinfo
   Reverse-merged /xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/test/java/org/apache/fop/intermediate/IFParserTestCase.java:r603620-746655


Property changes on: test/java/org/apache/fop/intermediate/AbstractIntermediateTestCase.java
___________________________________________________________________
Modified: svn:mergeinfo
   Reverse-merged /xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/test/java/org/apache/fop/intermediate/AbstractIntermediateTestCase.java:r603620-746655


Property changes on: test/java/org/apache/fop/intermediate/AreaTreeXMLFormatTestSuite.java
___________________________________________________________________
Modified: svn:mergeinfo
   Reverse-merged /xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/test/java/org/apache/fop/intermediate/AreaTreeXMLFormatTestSuite.java:r603620-746655

Index: test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java
===================================================================
--- test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java (.../trunk) (revision 824832)
+++ test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -99,7 +99,8 @@
         foFile = new File(foBaseDir, "with-cmyk-images.fo");
         try {
             convertFO(foFile, getUserAgent(), dumpPDF);
-            fail("Expected PDFConformanceException. PDF/A-1 does not allow PostScript XObjects.");
+            fail("Expected PDFConformanceException."
+                    + " PDF/A-1 does not allow mixing DeviceRGB and DeviceCMYK.");
         } catch (PDFConformanceException e) {
             //Good!
         }
Index: test/java/org/apache/fop/util/XMLUtilTestCase.java
===================================================================
--- test/java/org/apache/fop/util/XMLUtilTestCase.java (.../trunk) (revision 0)
+++ test/java/org/apache/fop/util/XMLUtilTestCase.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,45 @@
+/*
+ * 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.util;
+
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@link XMLUtil}.
+ */
+public class XMLUtilTestCase extends TestCase {
+
+    public void testLocaleToRFC3066() throws Exception {
+        assertNull(XMLUtil.toRFC3066(null));
+        assertEquals("en", XMLUtil.toRFC3066(new Locale("en")));
+        assertEquals("en-US", XMLUtil.toRFC3066(new Locale("en", "US")));
+        assertEquals("en-US", XMLUtil.toRFC3066(new Locale("EN", "us")));
+    }
+
+    public void testRFC3066ToLocale() throws Exception {
+        assertNull(XMLUtil.convertRFC3066ToLocale(null));
+        assertNull(XMLUtil.convertRFC3066ToLocale(""));
+        assertEquals(new Locale("en"), XMLUtil.convertRFC3066ToLocale("en"));
+        assertEquals(new Locale("en", "US"), XMLUtil.convertRFC3066ToLocale("en-US"));
+        assertEquals(new Locale("en", "US"), XMLUtil.convertRFC3066ToLocale("EN-us"));
+    }
+}

Property changes on: test/java/org/apache/fop/util/XMLUtilTestCase.java
___________________________________________________________________
Added: svn:eol-style
   + native
Added: svn:keywords
   + Id

Index: test/accessibility/background-image_svg_repeat.fo
===================================================================
--- test/accessibility/background-image_svg_repeat.fo (.../trunk) (revision 0)
+++ test/accessibility/background-image_svg_repeat.fo (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,34 @@
+<?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 background-image="../resources/images/rgb-circles.svg"/>
+    </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" text-align="justify">
+      <fo:block>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:flow>
+  </fo:page-sequence>
+</fo:root>

Property changes on: test/accessibility/background-image_svg_repeat.fo
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: test/accessibility/config-painter.xconf
===================================================================
--- test/accessibility/config-painter.xconf (.../trunk) (revision 0)
+++ test/accessibility/config-painter.xconf (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<fop version="1.0">
+  <accessibility>true</accessibility>
+  <source-resolution>144</source-resolution>
+  <use-cache>false</use-cache>
+  <font-base>../resources/fonts/</font-base>
+  <renderers>
+    <renderer mime="application/pdf">
+      <filterList>
+        <value>null</value>
+      </filterList>
+      <filterList type="image">
+        <value>flate</value>
+        <value>ascii-85</value>
+      </filterList>
+      <fonts>
+        <font embed-url="DejaVuLGCSerif.ttf">
+          <font-triplet name="DejaVu" style="normal" weight="normal"/>
+        </font>
+      </fonts>
+    </renderer>
+  </renderers>
+</fop>
Index: test/accessibility/background-image_svg_single.fo
===================================================================
--- test/accessibility/background-image_svg_single.fo (.../trunk) (revision 0)
+++ test/accessibility/background-image_svg_single.fo (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,36 @@
+<?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 background-image="../resources/images/rgb-circles.svg"
+        background-repeat="no-repeat" background-position-horizontal="50%"
+        background-position-vertical="50%"/>
+    </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" text-align="justify">
+      <fo:block>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:flow>
+  </fo:page-sequence>
+</fo:root>

Property changes on: test/accessibility/background-image_svg_single.fo
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: test/accessibility/links.fo
===================================================================
--- test/accessibility/links.fo (.../trunk) (revision 0)
+++ test/accessibility/links.fo (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,41 @@
+<?xml version="1.0" standalone="no"?>
+<!--
+  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"
+  xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
+  <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" text-align="justify">
+      <fo:block>This is a <fo:wrapper color="blue"><fo:basic-link
+            internal-destination="FOP">link</fo:basic-link></fo:wrapper> to the next
+        paragraph.</fo:block>
+      <fo:block id="FOP">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>For more information, see the <fo:wrapper color="blue"><fo:basic-link
+            external-destination="http://xmlgraphics.apache.org/fop/">FOP
+            website</fo:basic-link></fo:wrapper>.</fo:block>
+    </fo:flow>
+  </fo:page-sequence>
+</fo:root>

Property changes on: test/accessibility/links.fo
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: test/accessibility/config-renderer.xconf
===================================================================
--- test/accessibility/config-renderer.xconf (.../trunk) (revision 0)
+++ test/accessibility/config-renderer.xconf (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<fop version="1.0">
+  <prefer-renderer>true</prefer-renderer>
+  <accessibility>true</accessibility>
+  <source-resolution>144</source-resolution>
+  <use-cache>false</use-cache>
+  <font-base>../resources/fonts/</font-base>
+  <renderers>
+    <renderer mime="application/pdf">
+      <filterList>
+        <value>null</value>
+      </filterList>
+      <filterList type="image">
+        <value>flate</value>
+        <value>ascii-85</value>
+      </filterList>
+      <fonts>
+        <font embed-url="DejaVuLGCSerif.ttf">
+          <font-triplet name="DejaVu" style="normal" weight="normal"/>
+        </font>
+      </fonts>
+    </renderer>
+  </renderers>
+</fop>
Index: test/accessibility/image_jpg.fo
===================================================================
--- test/accessibility/image_jpg.fo (.../trunk) (revision 0)
+++ test/accessibility/image_jpg.fo (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,35 @@
+<?xml version="1.0" standalone="no"?>
+<!--
+  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"
+  xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
+  <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" text-align="justify">
+      <fo:block>This document contains an image in the JPEG format: <fo:external-graphic
+          src="../resources/images/cmyk.jpg"
+          inline-progression-dimension.maximum="100%" content-width="scale-to-fit"
+          fox:alt-text="CMYK colours"/>. Here is the end of the text.</fo:block>
+    </fo:flow>
+  </fo:page-sequence>
+</fo:root>

Property changes on: test/accessibility/image_jpg.fo
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: test/accessibility/text_font-embedding.fo
===================================================================
--- test/accessibility/text_font-embedding.fo (.../trunk) (revision 0)
+++ test/accessibility/text_font-embedding.fo (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,34 @@
+<?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" text-align="justify" font-family="DejaVu">
+      <fo:block>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:flow>
+  </fo:page-sequence>
+</fo:root>

Property changes on: test/accessibility/text_font-embedding.fo
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: test/accessibility/image_png.fo
===================================================================
--- test/accessibility/image_png.fo (.../trunk) (revision 0)
+++ test/accessibility/image_png.fo (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,35 @@
+<?xml version="1.0" standalone="no"?>
+<!--
+  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"
+  xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
+  <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" text-align="justify">
+      <fo:block>This document contains an image in the PNG format: <fo:external-graphic
+          src="../resources/images/fop-logo-color-24bit.png"
+          inline-progression-dimension.maximum="100%" content-width="scale-to-fit"
+          fox:alt-text="FOP Logo"/>. Here is the end of the text.</fo:block>
+    </fo:flow>
+  </fo:page-sequence>
+</fo:root>

Property changes on: test/accessibility/image_png.fo
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: test/accessibility/README
===================================================================
--- test/accessibility/README (.../trunk) (revision 0)
+++ test/accessibility/README (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,52 @@
+his 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,
+the text_1.fo file has been rendered into pdf/text_1_painter_orig.pdf and
+pdf/text_1_renderer_orig.pdf. The configuration file config-painter.xconf (resp.
+config-renderer.xconf) was used.
+
+The PDF files have been checked with Adobe Acrobat Professional 9, using both
+the full accessibility checker and the read-aloud feature. The checker reports
+no error /and/ the entire document can be read aloud.
+
+
+!! DO NOT MODIFY THOSE FILES, NEITHER THE FO NOR THE PDF !!
+
+
+... Or at least, know what you are doing
+If the FO files are modified, the resulting PDFs must be checked again, both
+with the checker and the read-aloud feature. (Sometimes the checker reports no
+problem yet part or all of the document cannot be read aloud.)
+
+The purpose of this infrastructure is to be able to quickly re-test the
+accessibility processing chain when any change has been made to it. The
+configuration files disable the compression of the PDF streams, so it is
+possible to compare a re-generated PDF with the original one by using a simple
+diff tool. The files will not be identical because of the different creation
+dates (and the ID key in the trailer), but apart from that there should be no
+difference.
+
+The rationale is that using a diff tool is much quicker and less tedious than
+running Acrobat's accessibility checker and read-aloud feature every time.
+
+
+To re-generate the PDF files using the painter:
+    ../../fop -c config-painter.xconf text_1.fo pdf/text_1_painter.pdf
+    diff pdf/text_1_painter_orig.pdf pdf/text_1_painter.pdf
+Or, going through the intermediate format:
+    ../../fop -c config-painter.xconf text_1.fo -if application/pdf text_1_if.xml
+    ../../fop -c config-painter.xconf -ifin text_1_if.xml pdf/text_1_painter.pdf
+    diff pdf/text_1_painter_orig.pdf pdf/text_1_painter.pdf
+
+To re-generate the PDF files using the legacy renderer:
+    ../../fop -c config-renderer.xconf text_1.fo pdf/text_1_renderer.pdf
+    diff pdf/text_1_renderer_orig.pdf pdf/text_1_renderer.pdf
+Or, going through the intermediate format:
+    ../../fop -c config-renderer.xconf text_1.fo -at application/pdf text_1_at.xml
+    ../../fop -c config-renderer.xconf -atin text_1_at.xml pdf/text_1_renderer.pdf
+    diff pdf/text_1_renderer_orig.pdf pdf/text_1_renderer.pdf
+
+
+$Id$

Property changes on: test/accessibility/README
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: test/accessibility/image_wmf.fo
===================================================================
--- test/accessibility/image_wmf.fo (.../trunk) (revision 0)
+++ test/accessibility/image_wmf.fo (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,35 @@
+<?xml version="1.0" standalone="no"?>
+<!--
+  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"
+  xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
+  <fo:layout-master-set>
+    <fo:simple-page-master master-name="page"
+      page-height="320pt" 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" text-align="justify">
+      <fo:block>This document contains an image in the WMF format: <fo:external-graphic
+          src="../resources/images/testChart.wmf"
+          inline-progression-dimension.maximum="100%" content-width="scale-to-fit"
+          fox:alt-text="Metafile Companion Test Chart"/> Here is the end of the text.</fo:block>
+    </fo:flow>
+  </fo:page-sequence>
+</fo:root>

Property changes on: test/accessibility/image_wmf.fo
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: test/accessibility/leader.fo
===================================================================
--- test/accessibility/leader.fo (.../trunk) (revision 0)
+++ test/accessibility/leader.fo (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,38 @@
+<?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" text-align="justify"
+      text-align-last="justify">
+      <fo:block>This is a text followed by a leader with leader-pattern=​"use-content", the
+        content being text:<fo:leader leader-pattern="use-content"><fo:inline> •
+      </fo:inline></fo:leader>1</fo:block>
+      <fo:block space-before="10pt">This is a text followed by a leader with
+        leader-pattern=​"use-content", the content being images:<fo:leader
+          leader-pattern="use-content"><fo:external-graphic
+            src="../resources/images/list-item.png"/></fo:leader>1</fo:block>
+    </fo:flow>
+  </fo:page-sequence>
+</fo:root>

Property changes on: test/accessibility/leader.fo
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: test/accessibility/background-image_jpg_repeat.fo
===================================================================
--- test/accessibility/background-image_jpg_repeat.fo (.../trunk) (revision 0)
+++ test/accessibility/background-image_jpg_repeat.fo (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,34 @@
+<?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 background-image="../resources/images/bgimg72dpi.jpg"/>
+    </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" text-align="justify">
+      <fo:block>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:flow>
+  </fo:page-sequence>
+</fo:root>

Property changes on: test/accessibility/background-image_jpg_repeat.fo
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: test/accessibility/background-image_jpg_single.fo
===================================================================
--- test/accessibility/background-image_jpg_single.fo (.../trunk) (revision 0)
+++ test/accessibility/background-image_jpg_single.fo (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,36 @@
+<?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 background-image="../resources/images/bgimg72dpi.jpg"
+        background-repeat="no-repeat" background-position-horizontal="50%"
+        background-position-vertical="50%"/>
+    </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" text-align="justify">
+      <fo:block>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:flow>
+  </fo:page-sequence>
+</fo:root>

Property changes on: test/accessibility/background-image_jpg_single.fo
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: test/accessibility/image_svg.fo
===================================================================
--- test/accessibility/image_svg.fo (.../trunk) (revision 0)
+++ test/accessibility/image_svg.fo (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,45 @@
+<?xml version="1.0" standalone="no"?>
+<!--
+  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"
+  xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
+  <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" text-align="justify">
+      <fo:block>This document contains an image in the SVG format: <fo:external-graphic
+          src="../resources/images/circles.svg"
+          inline-progression-dimension.maximum="75pt" content-width="scale-to-fit"
+          fox:alt-text="Nice circles"/>. And here is the same image as an instream-foreign-object:
+        <fo:instream-foreign-object inline-progression-dimension.maximum="75pt"
+          content-width="scale-down-to-fit" fox:alt-text="The same nice circles">
+<svg xmlns="http://www.w3.org/2000/svg" width="12cm" height="12cm">
+  <g style="fill-opacity:0.7; stroke:black; stroke-width:0.1cm;">
+    <circle cx="6cm" cy="2cm" r="100" style="fill:red;" transform="translate(0,50)" />
+    <circle cx="6cm" cy="2cm" r="100" style="fill:blue;" transform="translate(70,150)" />
+    <circle cx="6cm" cy="2cm" r="100" style="fill:green;" transform="translate(-70,150)"/>
+  </g>
+</svg>
+      </fo:instream-foreign-object>.</fo:block>
+    </fo:flow>
+  </fo:page-sequence>
+</fo:root>

Property changes on: test/accessibility/image_svg.fo
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: test/accessibility/background-image_png_repeat.fo
===================================================================
--- test/accessibility/background-image_png_repeat.fo (.../trunk) (revision 0)
+++ test/accessibility/background-image_png_repeat.fo (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,34 @@
+<?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 background-image="../resources/images/bgimg72dpi.png"/>
+    </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" text-align="justify">
+      <fo:block>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:flow>
+  </fo:page-sequence>
+</fo:root>

Property changes on: test/accessibility/background-image_png_repeat.fo
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: test/accessibility/background-image_png_single.fo
===================================================================
--- test/accessibility/background-image_png_single.fo (.../trunk) (revision 0)
+++ test/accessibility/background-image_png_single.fo (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,36 @@
+<?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 background-image="../resources/images/fop-logo-color-24bit.png"
+        background-repeat="no-repeat" background-position-horizontal="50%"
+        background-position-vertical="50%"/>
+    </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" text-align="justify">
+      <fo:block>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:flow>
+  </fo:page-sequence>
+</fo:root>

Property changes on: test/accessibility/background-image_png_single.fo
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: test/accessibility/text_1.fo
===================================================================
--- test/accessibility/text_1.fo (.../trunk) (revision 0)
+++ test/accessibility/text_1.fo (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,34 @@
+<?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" text-align="justify">
+      <fo:block>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:flow>
+  </fo:page-sequence>
+</fo:root>

Property changes on: test/accessibility/text_1.fo
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: test/accessibility/text_2.fo
===================================================================
--- test/accessibility/text_2.fo (.../trunk) (revision 0)
+++ test/accessibility/text_2.fo (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,41 @@
+<?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" text-align="justify">
+      <fo:block>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 language="fr" country="FR">Apache FOP (Formatting Objects Processor) est une
+        application de mise en page de documents respectant le standard XSL-FO. À partir d’un
+        document au format XSL-FO, cette application écrite en Java effectue une mise en page et
+        renvoie un document prêt pour impression.</fo:block>
+      <fo:block>Back to English and let’s say it again: Apache FOP (Formatting Objects Processor) is
+        a print formatter driven by XSL formatting objects (XSL-FO) and an output independent
+        formatter.</fo:block>
+    </fo:flow>
+  </fo:page-sequence>
+</fo:root>

Property changes on: test/accessibility/text_2.fo
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: test/accessibility/pdf/image_svg_renderer_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/image_svg_renderer_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/background-image_png_repeat_renderer_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/background-image_png_repeat_renderer_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/background-image_png_single_renderer_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/background-image_png_single_renderer_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/complete_renderer_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/complete_renderer_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/background-image_svg_repeat_painter_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/background-image_svg_repeat_painter_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/image_jpg_painter_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/image_jpg_painter_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/links_renderer_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/links_renderer_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/image_png_painter_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/image_png_painter_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/text_font-embedding_renderer_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/text_font-embedding_renderer_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/image_wmf_painter_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/image_wmf_painter_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/image_wmf_renderer_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/image_wmf_renderer_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/leader_renderer_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/leader_renderer_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/background-image_jpg_single_painter_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/background-image_jpg_single_painter_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/background-image_png_single_painter_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/background-image_png_single_painter_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/text_2_painter_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/text_2_painter_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/complete_painter_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/complete_painter_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/text_1_renderer_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/text_1_renderer_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/text_2_renderer_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/text_2_renderer_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/background-image_svg_single_painter_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/background-image_svg_single_painter_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/links_painter_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/links_painter_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/background-image_svg_repeat_renderer_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/background-image_svg_repeat_renderer_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/background-image_svg_single_renderer_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/background-image_svg_single_renderer_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/image_jpg_renderer_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/image_jpg_renderer_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/text_font-embedding_painter_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/text_font-embedding_painter_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/image_png_renderer_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/image_png_renderer_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/leader_painter_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/leader_painter_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/background-image_jpg_repeat_painter_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/background-image_jpg_repeat_painter_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/image_svg_painter_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/image_svg_painter_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/background-image_png_repeat_painter_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/background-image_png_repeat_painter_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/background-image_jpg_repeat_renderer_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/background-image_jpg_repeat_renderer_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/background-image_jpg_single_renderer_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/background-image_jpg_single_renderer_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/pdf/text_1_painter_orig.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/accessibility/pdf/text_1_painter_orig.pdf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/accessibility/complete.fo
===================================================================
--- test/accessibility/complete.fo (.../trunk) (revision 0)
+++ test/accessibility/complete.fo (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,205 @@
+<?xml version="1.0" standalone="no"?>
+<!--
+  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"
+  xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
+  <fo:layout-master-set>
+    <fo:simple-page-master master-name="page"
+      page-height="220pt" page-width="320pt" margin="10pt">
+      <fo:region-body column-count="2" margin-top="15pt"/>
+      <fo:region-before extent="12pt"/>
+    </fo:simple-page-master>
+  </fo:layout-master-set>
+  <fo:page-sequence master-reference="page" language="en" country="GB">
+    <fo:static-content flow-name="xsl-region-before">
+      <fo:block font-size="8pt" text-align-last="justify">This is the page header<fo:leader/>Page
+        <fo:page-number/></fo:block>
+    </fo:static-content>
+    <fo:static-content flow-name="xsl-footnote-separator">
+      <fo:block><fo:leader leader-length="100pt" leader-pattern="rule"/></fo:block>
+    </fo:static-content>
+    <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
+                  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:
+        <fo:external-graphic src="../resources/images/fop-logo-color-24bit.png"
+          inline-progression-dimension.maximum="100%" content-width="scale-to-fit"
+          fox:alt-text="FOP Logo"/></fo:block>
+      <fo:table space-before="10pt" space-after="10pt" width="100%" table-layout="fixed">
+        <fo:table-header>
+          <fo:table-row>
+            <fo:table-cell border="2pt solid black" padding="2pt 2pt 0">
+              <fo:block>Header 1.1</fo:block>
+            </fo:table-cell>
+            <fo:table-cell border="2pt solid black" padding="2pt 2pt 0">
+              <fo:block>Header 1.2</fo:block>
+            </fo:table-cell>
+          </fo:table-row>
+        </fo:table-header>
+        <fo:table-body>
+          <fo:table-row>
+            <fo:table-cell border="1pt solid black" padding="2pt 2pt 0">
+              <fo:block>Cell 1.1</fo:block>
+            </fo:table-cell>
+            <fo:table-cell border="1pt solid black" padding="2pt 2pt 0">
+              <fo:block>Cell 1.2</fo:block>
+            </fo:table-cell>
+          </fo:table-row>
+          <fo:table-row>
+            <fo:table-cell border="1pt solid black" padding="2pt 2pt 0">
+              <fo:block>Cell 2.1</fo:block>
+            </fo:table-cell>
+            <fo:table-cell border="1pt solid black" padding="2pt 2pt 0">
+              <fo:block>Cell 2.2</fo:block>
+            </fo:table-cell>
+          </fo:table-row>
+        </fo:table-body>
+      </fo:table>
+      <fo:block>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 span="all" border-top="1pt solid black" border-bottom="1pt solid black"
+        padding-before="2pt" padding-after="2pt">This fo:block element spans all the columns of the
+        document. This is intended to test the abilities of the text-to-speech program.</fo:block>
+      <fo:block>And now we are back to normal content flowing in two columns. Let’s start a numbered
+        list:</fo:block>
+      <fo:list-block provisional-distance-between-starts="15pt" provisional-label-separation="0mm"
+        keep-with-previous="auto">
+        <fo:list-item keep-with-previous="always">
+          <fo:list-item-label end-indent="label-end()">
+            <fo:block>1.</fo:block>
+          </fo:list-item-label>
+          <fo:list-item-body start-indent="body-start()">
+            <fo:block>
+              <fo:block>Line 1 of item 1</fo:block>
+              <fo:block>Line 2 of item 1</fo:block>
+              <fo:block>Line 3 of item 1</fo:block>
+            </fo:block>
+          </fo:list-item-body>
+        </fo:list-item>
+        <fo:list-item keep-with-previous="always">
+          <fo:list-item-label end-indent="label-end()">
+            <fo:block>2.</fo:block>
+          </fo:list-item-label>
+          <fo:list-item-body start-indent="body-start()">
+            <fo:block>
+              <fo:block>Line 1 of item 2</fo:block>
+              <fo:block>Line 2 of item 2</fo:block>
+              <fo:block>Line 3 of item 2</fo:block>
+            </fo:block>
+          </fo:list-item-body>
+        </fo:list-item>
+      </fo:list-block>
+      <fo:block>And now we are going to see how a second page sequence is handled.</fo:block>
+    </fo:flow>
+  </fo:page-sequence>
+  <fo:page-sequence master-reference="page" language="en" country="GB">
+    <fo:static-content flow-name="xsl-region-before">
+      <fo:block font-size="8pt" text-align-last="justify">This is the page header<fo:leader/>Page
+        <fo:page-number/></fo:block>
+    </fo:static-content>
+    <fo:static-content flow-name="xsl-footnote-separator">
+      <fo:block><fo:leader leader-length="100pt" leader-pattern="rule"/></fo:block>
+    </fo:static-content>
+    <fo:flow flow-name="xsl-region-body" hyphenate="true" text-align="justify">
+      <fo:block id="second">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
+                  external-destination="http://xmlgraphics.apache.org/fop/">FOP
+                  website</fo:basic-link></fo:wrapper> for more
+              information</fo:block></fo:footnote-body></fo:footnote>. It is a Java application that
+        reads a formatting object (FO) tree and renders the resulting pages to a specified
+        output.</fo:block>
+      <fo:table space-before="10pt" space-after="10pt" width="100%" table-layout="fixed">
+        <fo:table-header>
+          <fo:table-row>
+            <fo:table-cell border="2pt solid black" padding="2pt 2pt 0">
+              <fo:block>Header 1.1</fo:block>
+            </fo:table-cell>
+            <fo:table-cell border="2pt solid black" padding="2pt 2pt 0">
+              <fo:block>Header 1.2</fo:block>
+            </fo:table-cell>
+          </fo:table-row>
+        </fo:table-header>
+        <fo:table-body>
+          <fo:table-row>
+            <fo:table-cell border="1pt solid black" padding="2pt 2pt 0">
+              <fo:block>Cell 1.1</fo:block>
+            </fo:table-cell>
+            <fo:table-cell border="1pt solid black" padding="2pt 2pt 0">
+              <fo:block>Cell 1.2</fo:block>
+            </fo:table-cell>
+          </fo:table-row>
+          <fo:table-row>
+            <fo:table-cell border="1pt solid black" padding="2pt 2pt 0">
+              <fo:block>Cell 2.1</fo:block>
+            </fo:table-cell>
+            <fo:table-cell border="1pt solid black" padding="2pt 2pt 0">
+              <fo:block>Cell 2.2</fo:block>
+            </fo:table-cell>
+          </fo:table-row>
+        </fo:table-body>
+      </fo:table>
+      <fo:block language="fr" country="FR">Apache FOP (Formatting Objects Processor) est une
+        application de mise en page de documents respectant le standard XSL-FO. À partir d’un
+        document au format XSL-FO, cette application écrite en Java effectue une mise en page et
+        renvoie un document prêt pour impression.</fo:block>
+      <fo:block span="all" border-top="1pt solid black" border-bottom="1pt solid black"
+        padding-before="2pt" padding-after="2pt">This fo:block element spans all the columns of the
+        document. This is intended to test the abilities of the text-to-speech program.</fo:block>
+      <fo:block>And now we are back to normal content flowing in two columns. Let’s start a numbered
+        list:</fo:block>
+      <fo:list-block provisional-distance-between-starts="15pt" provisional-label-separation="0mm"
+        keep-with-previous="auto">
+        <fo:list-item keep-with-previous="always">
+          <fo:list-item-label end-indent="label-end()">
+            <fo:block>1.</fo:block>
+          </fo:list-item-label>
+          <fo:list-item-body start-indent="body-start()">
+            <fo:block>
+              <fo:block>Line 1 of item 1</fo:block>
+              <fo:block>Line 2 of item 1</fo:block>
+              <fo:block>Line 3 of item 1</fo:block>
+            </fo:block>
+          </fo:list-item-body>
+        </fo:list-item>
+        <fo:list-item keep-with-previous="always">
+          <fo:list-item-label end-indent="label-end()">
+            <fo:block>2.</fo:block>
+          </fo:list-item-label>
+          <fo:list-item-body start-indent="body-start()">
+            <fo:block>
+              <fo:block>Line 1 of item 2</fo:block>
+              <fo:block>Line 2 of item 2</fo:block>
+              <fo:block>Line 3 of item 2</fo:block>
+            </fo:block>
+          </fo:list-item-body>
+        </fo:list-item>
+      </fo:list-block>
+      <fo:block>The end of the document has now been reached.</fo:block>
+    </fo:flow>
+  </fo:page-sequence>
+</fo:root>

Property changes on: test/accessibility/complete.fo
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: test/layoutengine/standard-testcases/page-sequence_language.xml
===================================================================
--- test/layoutengine/standard-testcases/page-sequence_language.xml (.../trunk) (revision 824832)
+++ test/layoutengine/standard-testcases/page-sequence_language.xml (.../branches/Temp_Accessibility) (revision 828760)
@@ -65,4 +65,10 @@
     <eval expected="de" xpath="/areaTree/pageSequence[4]/@language"/>
     <true xpath="not(boolean(/areaTree/pageSequence[4]/@country))"/>
   </checks>
+  <if-checks xmlns:if="http://xmlgraphics.apache.org/fop/intermediate">
+    <eval expected="en" xpath="//if:page-sequence[1]/@xml:lang"/>
+    <eval expected="en-US" xpath="//if:page-sequence[2]/@xml:lang"/>
+    <eval expected="de-CH" xpath="//if:page-sequence[3]/@xml:lang"/>
+    <eval expected="de" xpath="//if:page-sequence[4]/@xml:lang"/>
+  </if-checks>
 </testcase>
Index: test/layoutengine/standard-testcases/foreign-attributes.xml
===================================================================
--- test/layoutengine/standard-testcases/foreign-attributes.xml (.../trunk) (revision 824832)
+++ test/layoutengine/standard-testcases/foreign-attributes.xml (.../branches/Temp_Accessibility) (revision 828760)
@@ -32,7 +32,7 @@
       <fo:page-sequence master-reference="normal">
         <fo:flow flow-name="xsl-region-body">
           <fo:block id="eg">
-            <fo:external-graphic src="../../resources/images/bgimg300dpi.jpg" fox:alt="description"/>
+            <fo:external-graphic src="../../resources/images/bgimg300dpi.jpg" fox:alt-text="description"/>
           </fo:block>
           <fo:block id="bl">
             <fo:basic-link external-destination="url(http://xmlgraphics.apache.org/fop/)" fox:blah="fop">FOP</fo:basic-link>
@@ -43,7 +43,7 @@
   </fo>
   <checks xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">
     <eval expected="bar" xpath="//pageViewport[1]/@fox:foo"/>
-    <eval expected="description" xpath="//block[@prod-id='eg']//image/@fox:alt"/>
+    <eval expected="description" xpath="//block[@prod-id='eg']//image/@fox:alt-text"/>
     <!--eval expected="fop" xpath="//block[@prod-id='bl']/inlineparent/@fox:blah"/> NYI -->
   </checks>
 </testcase>
Index: test/resources/images/list-item.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: test/resources/images/list-item.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: test/resources/images/rgb-circles.svg
===================================================================
--- test/resources/images/rgb-circles.svg (.../trunk) (revision 0)
+++ test/resources/images/rgb-circles.svg (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="319" height="286.6">
+  <g style="fill-opacity:0.7; stroke:black; stroke-width:3"
+    transform="translate(0, 286.6) scale(1, -1) translate(100, 100)">
+    <circle cx="50"  cy="86.6" r="80" style="fill:red;"/>
+    <circle cx="0"   cy="0"    r="80" style="fill:green;"/>
+    <circle cx="100" cy="0"    r="80" style="fill:blue;"/>
+  </g>
+</svg>

Property changes on: test/resources/images/rgb-circles.svg
___________________________________________________________________
Added: svn:eol-style
   + native

Index: status.xml
===================================================================
--- status.xml (.../trunk) (revision 824832)
+++ status.xml (.../branches/Temp_Accessibility) (revision 828760)
@@ -58,6 +58,9 @@
       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="JM" type="add" fixes-bug="46705" due-to="Jost Klopfstein">
+        Added basic accessibility and Tagged PDF support.
+      </action>
       <action context="Layout" dev="VH" type="fix">
         Fixed handling of percentage values for provisional-label-separation.
       </action>
@@ -463,7 +466,7 @@
           <p>
             Besides the important changes listed below, the most important areas with
             improvements in this release are:
-          </p>
+         </p>
           <ul>
             <li>
               Many bugfixes in tables, plus some new features (full support for keeps and
Index: src/java/META-INF/services/org.apache.fop.fo.ElementMapping
===================================================================
--- src/java/META-INF/services/org.apache.fop.fo.ElementMapping (.../trunk) (revision 824832)
+++ src/java/META-INF/services/org.apache.fop.fo.ElementMapping (.../branches/Temp_Accessibility) (revision 828760)
@@ -1,10 +1,11 @@
-org.apache.fop.fo.FOElementMapping
-org.apache.fop.fo.extensions.svg.SVGElementMapping
-org.apache.fop.fo.extensions.svg.BatikExtensionElementMapping
-org.apache.fop.fo.extensions.ExtensionElementMapping
-org.apache.fop.fo.extensions.OldExtensionElementMapping
-org.apache.fop.fo.extensions.xmp.XMPElementMapping
-org.apache.fop.fo.extensions.xmp.RDFElementMapping
-org.apache.fop.render.ps.extensions.PSExtensionElementMapping
-org.apache.fop.render.afp.extensions.AFPElementMapping
+org.apache.fop.fo.FOElementMapping
+org.apache.fop.fo.extensions.svg.SVGElementMapping
+org.apache.fop.fo.extensions.svg.BatikExtensionElementMapping
+org.apache.fop.fo.extensions.ExtensionElementMapping
+org.apache.fop.fo.extensions.InternalElementMapping
+org.apache.fop.fo.extensions.OldExtensionElementMapping
+org.apache.fop.fo.extensions.xmp.XMPElementMapping
+org.apache.fop.fo.extensions.xmp.RDFElementMapping
+org.apache.fop.render.ps.extensions.PSExtensionElementMapping
+org.apache.fop.render.afp.extensions.AFPElementMapping
 org.apache.fop.render.pcl.extensions.PCLElementMapping
\ No newline at end of file

Property changes on: src/java/META-INF/services/org.apache.fop.render.intermediate.IFDocumentHandler
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /xmlgraphics/fop/trunk/src/java/META-INF/services/org.apache.fop.render.intermediate.IFDocumentHandler:r699793-824832


Property changes on: src/java/org/apache/fop/render/AbstractRenderingContext.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/RendererContext.java:r603620-680380

Index: src/java/org/apache/fop/render/rtf/RTFEventProducer.xml
===================================================================
--- src/java/org/apache/fop/render/rtf/RTFEventProducer.xml (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/rtf/RTFEventProducer.xml (.../branches/Temp_Accessibility) (revision 828760)
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<catalogue xml:lang="en">
+<?xml version="1.0" encoding="UTF-8"?><catalogue xml:lang="en">
   <message key="locator">[ (See position {loc})| (See {#gatherContextInfo})| (No context info available)]</message>
   <message key="org.apache.fop.render.rtf.RTFEventProducer.onlySPMSupported">Only simple-page-masters are supported on page-sequences. Using default simple-page-master from page-sequence-master "{masterReference}".{{locator}}</message>
   <message key="org.apache.fop.render.rtf.RTFEventProducer.noSPMFound">No simple-page-master could be determined.</message>

Property changes on: src/java/org/apache/fop/render/intermediate/AbstractIFDocumentHandlerMaker.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/branches/fop-0_95/src/java/org/apache/fop/render/intermediate/AbstractIFPainterMaker.java:r684572
   Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/AbstractIFPainterMaker.java:r603620-685574

Index: src/java/org/apache/fop/render/intermediate/IFContext.java
===================================================================
--- src/java/org/apache/fop/render/intermediate/IFContext.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/intermediate/IFContext.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -20,6 +20,7 @@
 package org.apache.fop.render.intermediate;
 
 import java.util.Collections;
+import java.util.Locale;
 import java.util.Map;
 
 import org.apache.xmlgraphics.util.QName;
@@ -43,6 +44,10 @@
     /** foreign attributes: Map<QName, Object> */
     private Map foreignAttributes = Collections.EMPTY_MAP;
 
+    private Locale language;
+
+    private String structurePointer;
+
     /**
      * Main constructor.
      * @param ua the user agent
@@ -108,4 +113,46 @@
         setForeignAttributes(null);
     }
 
+    /**
+     * Sets the currently applicable language.
+     * @param lang the language
+     */
+    public void setLanguage(Locale lang) {
+        this.language = lang;
+    }
+
+    /**
+     * Returns the currently applicable language.
+     * @return the language (or null if the language is undefined)
+     */
+    public Locale getLanguage() {
+        return this.language;
+    }
+
+    /**
+     * Sets the structure pointer for the following painted marks. This method is used when
+     * accessibility features are enabled.
+     * @param ptr the structure pointer
+     */
+    public void setStructurePointer(String ptr) {
+        this.structurePointer = ptr;
+    }
+
+    /**
+     * Resets the current structure pointer.
+     * @see #setStructurePointer(String)
+     */
+    public void resetStructurePointer() {
+        setStructurePointer(null);
+    }
+
+    /**
+     * Returns the current structure pointer.
+     * @return the structure pointer (or null if no pointer is active)
+     * @see #setStructurePointer(String)
+     */
+    public String getStructurePointer() {
+        return this.structurePointer;
+    }
+
 }

Property changes on: src/java/org/apache/fop/render/intermediate/AbstractXMLWritingIFDocumentHandler.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/branches/fop-0_95/src/java/org/apache/fop/render/intermediate/AbstractXMLWritingIFPainter.java:r684572
   Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/AbstractXMLWritingIFPainter.java:r603620-685574

Index: src/java/org/apache/fop/render/intermediate/IFParser.java
===================================================================
--- src/java/org/apache/fop/render/intermediate/IFParser.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/intermediate/IFParser.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -25,6 +25,7 @@
 import java.awt.Rectangle;
 import java.awt.geom.AffineTransform;
 import java.util.Map;
+import java.util.Set;
 
 import javax.xml.transform.Source;
 import javax.xml.transform.Transformer;
@@ -34,7 +35,6 @@
 
 import org.w3c.dom.DOMImplementation;
 import org.w3c.dom.Document;
-
 import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
@@ -46,6 +46,8 @@
 
 import org.apache.xmlgraphics.util.QName;
 
+import org.apache.fop.accessibility.AccessibilityEventProducer;
+import org.apache.fop.accessibility.StructureTreeBuilder;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fo.ElementMapping;
 import org.apache.fop.fo.ElementMappingRegistry;
@@ -59,6 +61,7 @@
 import org.apache.fop.util.ContentHandlerFactoryRegistry;
 import org.apache.fop.util.DOMBuilderContentHandlerFactory;
 import org.apache.fop.util.DefaultErrorListener;
+import org.apache.fop.util.DelegatingContentHandler;
 import org.apache.fop.util.XMLUtil;
 
 /**
@@ -73,6 +76,15 @@
     private static SAXTransformerFactory tFactory
         = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
 
+    private static Set handledNamespaces = new java.util.HashSet();
+
+    static {
+        handledNamespaces.add(XMLNS_NAMESPACE_URI);
+        handledNamespaces.add(XML_NAMESPACE);
+        handledNamespaces.add(NAMESPACE);
+        handledNamespaces.add(XLINK_NAMESPACE);
+    }
+
     /**
      * Parses an intermediate file and paints it.
      * @param src the Source instance pointing to the intermediate file
@@ -140,6 +152,26 @@
 
         private ContentHandler navParser;
 
+        private StructureTreeBuilder structureTreeBuilder;
+
+        private ContentHandler structureTreeBuilderWrapper;
+
+        private Attributes pageSequenceAttributes;
+
+        private final class StructureTreeBuilderWrapper extends DelegatingContentHandler {
+
+            private StructureTreeBuilderWrapper()
+                    throws SAXException {
+                super(structureTreeBuilder.getHandlerForNextPageSequence());
+            }
+
+            public void endDocument() throws SAXException {
+                super.endDocument();
+                startIFElement(EL_PAGE_SEQUENCE, pageSequenceAttributes);
+                pageSequenceAttributes = null;
+            }
+        }
+
         public Handler(IFDocumentHandler documentHandler, FOUserAgent userAgent,
                 ElementMappingRegistry elementMappingRegistry) {
             this.documentHandler = documentHandler;
@@ -163,6 +195,11 @@
             elementHandlers.put(EL_LINE, new LineHandler());
             elementHandlers.put(EL_BORDER_RECT, new BorderRectHandler());
             elementHandlers.put(EL_IMAGE, new ImageHandler());
+
+            if (userAgent.isAccessibilityEnabled()) {
+                structureTreeBuilder = new StructureTreeBuilder(tFactory);
+                userAgent.setStructureTree(structureTreeBuilder.getStructureTree());
+            }
         }
 
         private void establishForeignAttributes(Map foreignAttributes) {
@@ -173,31 +210,50 @@
             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 {
             if (delegate != null) {
-                //delegateStack.push(qName);
                 delegateDepth++;
                 delegate.startElement(uri, localName, qName, attributes);
             } else {
                 boolean handled = true;
                 if (NAMESPACE.equals(uri)) {
-                    lastAttributes = new AttributesImpl(attributes);
-                    ElementHandler elementHandler = (ElementHandler)elementHandlers.get(localName);
-                    content.setLength(0);
-                    ignoreCharacters = true;
-                    if (elementHandler != null) {
-                        ignoreCharacters = elementHandler.ignoreCharacters();
-                        try {
-                            elementHandler.startElement(attributes);
-                        } catch (IFException ife) {
-                            handleIFException(ife);
+                    if (localName.equals(EL_PAGE_SEQUENCE) && userAgent.isAccessibilityEnabled()) {
+                        pageSequenceAttributes = new AttributesImpl(attributes);
+                        structureTreeBuilderWrapper = new StructureTreeBuilderWrapper();
+                    } else if (localName.equals(EL_STRUCTURE_TREE)) {
+                        if (userAgent.isAccessibilityEnabled()) {
+                            delegate = structureTreeBuilderWrapper;
+                        } else {
+                            /* Delegate to a handler that does nothing */
+                            delegate = new DefaultHandler();
                         }
-                    } else if ("extension-attachments".equals(localName)) {
-                        //TODO implement me
+                        delegateDepth++;
+                        delegate.startDocument();
+                        delegate.startElement(uri, localName, qName, attributes);
                     } else {
-                        handled = false;
+                        if (pageSequenceAttributes != null) {
+                            /*
+                             * This means that no structure-element tag was
+                             * found in the XML, otherwise a
+                             * StructureTreeBuilderWrapper object would have
+                             * been created, which would have reset the
+                             * pageSequenceAttributes field.
+                             */
+                            AccessibilityEventProducer.Provider
+                                    .get(userAgent.getEventBroadcaster())
+                                    .noStructureTreeInXML(this);
+                        }
+                        handled = startIFElement(localName, attributes);
                     }
                 } else if (DocumentNavigationExtensionConstants.NAMESPACE.equals(uri)) {
                     if (this.navParser == null) {
@@ -241,6 +297,25 @@
             }
         }
 
+        private boolean startIFElement(String localName, Attributes attributes)
+                throws SAXException {
+            lastAttributes = new AttributesImpl(attributes);
+            ElementHandler elementHandler = (ElementHandler)elementHandlers.get(localName);
+            content.setLength(0);
+            ignoreCharacters = true;
+            if (elementHandler != null) {
+                ignoreCharacters = elementHandler.ignoreCharacters();
+                try {
+                    elementHandler.startElement(attributes);
+                } catch (IFException ife) {
+                    handleIFException(ife);
+                }
+                return true;
+            } else {
+                return false;
+            }
+        }
+
         private void handleIFException(IFException ife) throws SAXException {
             if (ife.getCause() instanceof SAXException) {
                 //unwrap
@@ -352,6 +427,11 @@
 
             public void startElement(Attributes attributes) throws IFException {
                 String id = attributes.getValue("id");
+                String xmllang = attributes.getValue(XML_NAMESPACE, "lang");
+                if (xmllang != null) {
+                    documentHandler.getContext().setLanguage(
+                            XMLUtil.convertRFC3066ToLocale(xmllang));
+                }
                 Map foreignAttributes = getForeignAttributes(lastAttributes);
                 establishForeignAttributes(foreignAttributes);
                 documentHandler.startPageSequence(id);
@@ -360,6 +440,7 @@
 
             public void endElement() throws IFException {
                 documentHandler.endPageSequence();
+                documentHandler.getContext().setLanguage(null);
             }
 
         }
@@ -484,7 +565,9 @@
                 s = lastAttributes.getValue("word-spacing");
                 int wordSpacing = (s != null ? Integer.parseInt(s) : 0);
                 int[] dx = XMLUtil.getAttributeAsIntArray(lastAttributes, "dx");
+                setStructurePointer(lastAttributes);
                 painter.drawText(x, y, letterSpacing, wordSpacing, dx, content.toString());
+                resetStructurePointer();
             }
 
             public boolean ignoreCharacters() {
@@ -579,6 +662,7 @@
                 int height = Integer.parseInt(lastAttributes.getValue("height"));
                 Map foreignAttributes = getForeignAttributes(lastAttributes);
                 establishForeignAttributes(foreignAttributes);
+                setStructurePointer(lastAttributes);
                 if (foreignObject != null) {
                     painter.drawImage(foreignObject,
                             new Rectangle(x, y, width, height));
@@ -592,6 +676,7 @@
                     painter.drawImage(uri, new Rectangle(x, y, width, height));
                 }
                 resetForeignAttributes();
+                resetStructurePointer();
                 inForeignObject = false;
             }
 
@@ -632,12 +717,8 @@
             for (int i = 0, c = atts.getLength(); i < c; i++) {
                 String ns = atts.getURI(i);
                 if (ns.length() > 0) {
-                    if ("http://www.w3.org/2000/xmlns/".equals(ns)) {
+                    if (handledNamespaces.contains(ns)) {
                         continue;
-                    } else if (NAMESPACE.equals(ns)) {
-                        continue;
-                    } else if (XLINK_NAMESPACE.equals(ns)) {
-                        continue;
                     }
                     if (foreignAttributes == null) {
                         foreignAttributes = new java.util.HashMap();
@@ -649,6 +730,13 @@
             return foreignAttributes;
         }
 
+        private void setStructurePointer(Attributes attributes) {
+            String ptr = attributes.getValue("ptr");
+            if (ptr != null && ptr.length() > 0) {
+                establishStructurePointer(ptr);
+            }
+        }
+
         /** {@inheritDoc} */
         public void characters(char[] ch, int start, int length) throws SAXException {
             if (delegate != null) {

Property changes on: src/java/org/apache/fop/render/intermediate/IFDocumentHandlerConfigurator.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/branches/fop-0_95/src/java/org/apache/fop/render/intermediate/IFPainterConfigurator.java:r684572
   Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFPainterConfigurator.java:r603620-685574

Index: src/java/org/apache/fop/render/intermediate/extensions/AbstractAction.java
===================================================================
--- src/java/org/apache/fop/render/intermediate/extensions/AbstractAction.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/intermediate/extensions/AbstractAction.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -27,6 +27,7 @@
 public abstract class AbstractAction implements XMLizable {
 
     private String id;
+    private String structurePointer;
 
     /**
      * Sets an ID to make the action referencable.
@@ -45,6 +46,22 @@
     }
 
     /**
+     * Sets the structure element corresponding to this action.
+     * @param structurePointer a reference to the structure element
+     */
+    public void setStructurePointer(String structurePointer) {
+        this.structurePointer = structurePointer;
+    }
+
+    /**
+     * Returns the structure element corresponding to this action.
+     * @return the reference to the structure element
+     */
+    public String getStructurePointer() {
+        return structurePointer;
+    }
+
+    /**
      * Indicates whether the action has an ID and is therefore referencable.
      * @return true if the action has an ID
      */

Property changes on: src/java/org/apache/fop/render/intermediate/extensions/DocumentNavigationExtensionConstants.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/extensions/DocumentNavigationExtensionConstants.java:r685127-824832

Index: src/java/org/apache/fop/render/intermediate/extensions/DocumentNavigationHandler.java
===================================================================
--- src/java/org/apache/fop/render/intermediate/extensions/DocumentNavigationHandler.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/intermediate/extensions/DocumentNavigationHandler.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -48,6 +48,8 @@
 
     private IFDocumentNavigationHandler navHandler;
 
+    private String structurePointer;
+
     /**
      * Main constructor.
      * @param navHandler the navigation handler that will receive the events
@@ -96,6 +98,7 @@
                     throw new SAXException(localName + " must be the root element!");
                 }
                 Rectangle targetRect = XMLUtil.getAttributeAsRectangle(attributes, "rect");
+                structurePointer = attributes.getValue("ptr");
                 Link link = new Link(null, targetRect);
                 objectStack.push(link);
             } else if (GOTO_XY.getLocalName().equals(localName)) {
@@ -118,6 +121,9 @@
                     }
                     action = new GoToXYAction(id, pageIndex, location);
                 }
+                if (structurePointer != null) {
+                    action.setStructurePointer(structurePointer);
+                }
                 objectStack.push(action);
             } else if (GOTO_URI.getLocalName().equals(localName)) {
                 String id = attributes.getValue("id");
@@ -128,6 +134,9 @@
                 if (id != null) {
                     action.setID(id);
                 }
+                if (structurePointer != null) {
+                    action.setStructurePointer(structurePointer);
+                }
                 objectStack.push(action);
             } else {
                 throw new SAXException(

Property changes on: src/java/org/apache/fop/render/intermediate/extensions/DocumentNavigationHandler.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/extensions/DocumentNavigationExtensionHandlerFactory.java:r685127-724689


Property changes on: src/java/org/apache/fop/render/intermediate/AbstractIFDocumentHandler.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/AbstractIFDocumentHandler.java:r699793-824832


Property changes on: src/java/org/apache/fop/render/intermediate/IFPainter.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFPainter.java:r680381-824832

Index: src/java/org/apache/fop/render/intermediate/IFRenderer.java
===================================================================
--- src/java/org/apache/fop/render/intermediate/IFRenderer.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/intermediate/IFRenderer.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -30,6 +30,7 @@
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Stack;
 
@@ -493,6 +494,7 @@
         try {
             if (this.inPageSequence) {
                 documentHandler.endPageSequence();
+                documentHandler.getContext().setLanguage(null);
             } else {
                 if (this.documentMetadata == null) {
                     this.documentMetadata = createDefaultDocumentMetadata();
@@ -502,6 +504,7 @@
                 this.inPageSequence = true;
             }
             establishForeignAttributes(pageSequence.getForeignAttributes());
+            documentHandler.getContext().setLanguage(toLocale(pageSequence));
             documentHandler.startPageSequence(null);
             resetForeignAttributes();
             processExtensionAttachments(pageSequence);
@@ -510,6 +513,17 @@
         }
     }
 
+    private Locale toLocale(PageSequence pageSequence) {
+        if (pageSequence.getLanguage() != null) {
+            if (pageSequence.getCountry() != null) {
+                return new Locale(pageSequence.getLanguage(), pageSequence.getCountry());
+            } else {
+                return new Locale(pageSequence.getLanguage());
+            }
+        }
+        return null;
+    }
+
     private Metadata createDefaultDocumentMetadata() {
         Metadata xmp = new Metadata();
         DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp);
@@ -604,6 +618,14 @@
         documentHandler.getContext().resetForeignAttributes();
     }
 
+    private void establishStructurePointer(String ptr) {
+        documentHandler.getContext().setStructurePointer(ptr);
+    }
+
+    private void resetStructurePointer() {
+        documentHandler.getContext().resetStructurePointer();
+    }
+
     /** {@inheritDoc} */
     protected void saveGraphicsState() {
         graphicContextStack.push(graphicContext);
@@ -824,17 +846,20 @@
             currentIPPosition = saveIP;
             currentBPPosition = saveBP;
 
-            currentBPPosition += (int)(bv.getAllocBPD());
+            currentBPPosition += bv.getAllocBPD();
         }
         viewportDimensionStack.pop();
     }
 
     /** {@inheritDoc} */
     public void renderViewport(Viewport viewport) {
+        String ptr = (String) viewport.getTrait(Trait.PTR);
+        establishStructurePointer(ptr);
         Dimension dim = new Dimension(viewport.getIPD(), viewport.getBPD());
         viewportDimensionStack.push(dim);
         super.renderViewport(viewport);
         viewportDimensionStack.pop();
+        resetStructurePointer();
     }
 
     /** {@inheritDoc} */
@@ -892,6 +917,7 @@
         // 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();
@@ -935,6 +961,7 @@
 
         // warn if link trait found but not allowed, else create link
         if (linkTraitFound) {
+            action.setStructurePointer(ptr);  // used for accessibility
             Link link = new Link(action, ipRect);
             this.deferredLinks.add(link);
         }
@@ -969,6 +996,8 @@
 
         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);
 
         // This assumes that *all* CIDFonts use a /ToUnicode mapping
         Typeface tf = getTypeface(fontName);
@@ -990,6 +1019,7 @@
 
         textUtil.flush();
         renderTextDecoration(tf, size, text, bl, rx);
+        resetStructurePointer();
     }
 
     /** {@inheritDoc} */
@@ -1060,10 +1090,10 @@
         private static final int INITIAL_BUFFER_SIZE = 16;
         private int[] dx = new int[INITIAL_BUFFER_SIZE];
         private int lastDXPos = 0;
-        private StringBuffer text = new StringBuffer();
+        private final StringBuffer text = new StringBuffer();
         private int startx, starty;
         private int tls, tws;
-        private boolean combined = false;
+        private final boolean combined = false;
 
         void addChar(char ch) {
             text.append(ch);

Property changes on: src/java/org/apache/fop/render/intermediate/IFRenderer.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFRenderer.java:r680381-824832


Property changes on: src/java/org/apache/fop/render/intermediate/IFContentHandler.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/IFContentHandler.java:r680381-824832


Property changes on: src/java/org/apache/fop/render/intermediate/AbstractBinaryWritingIFDocumentHandler.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/branches/fop-0_95/src/java/org/apache/fop/render/intermediate/AbstractBinaryWritingIFPainter.java:r684572
   Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/intermediate/AbstractBinaryWritingIFPainter.java:r603620-685574

Index: src/java/org/apache/fop/render/intermediate/IFSerializer.java
===================================================================
--- src/java/org/apache/fop/render/intermediate/IFSerializer.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/intermediate/IFSerializer.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -27,16 +27,19 @@
 import java.awt.geom.AffineTransform;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 
 import org.w3c.dom.Document;
-
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.AttributesImpl;
 
 import org.apache.xmlgraphics.util.QName;
 import org.apache.xmlgraphics.util.XMLizable;
 
+import org.apache.fop.accessibility.StructureTree;
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.render.PrintRendererConfigurator;
 import org.apache.fop.render.RenderingContext;
@@ -60,6 +63,7 @@
         implements IFConstants, IFPainter, IFDocumentNavigationHandler {
 
     private IFDocumentHandler mimicHandler;
+    private int pageSequenceIndex; // used for accessibility
 
     /** Holds the intermediate format state */
     private IFState state;
@@ -210,8 +214,23 @@
             if (id != null) {
                 atts.addAttribute(XML_NAMESPACE, "id", "xml:id", XMLUtil.CDATA, id);
             }
+            Locale lang = getContext().getLanguage();
+            if (lang != null) {
+                atts.addAttribute(XML_NAMESPACE, "lang", "xml:lang", XMLUtil.CDATA,
+                        XMLUtil.toRFC3066(lang));
+            }
             addForeignAttributes(atts);
             handler.startElement(EL_PAGE_SEQUENCE, atts);
+            if (this.getUserAgent().isAccessibilityEnabled()) {
+                StructureTree structureTree = getUserAgent().getStructureTree();
+                handler.startElement(EL_STRUCTURE_TREE); // add structure tree
+                NodeList nodes = structureTree.getPageSequence(pageSequenceIndex++);
+                for (int i = 0, n = nodes.getLength(); i < n; i++) {
+                    Node node = nodes.item(i);
+                    new DOM2SAX(handler).writeFragment(node);
+                }
+                handler.endElement(EL_STRUCTURE_TREE);
+            }
         } catch (SAXException e) {
             throw new IFException("SAX error in startPageSequence()", e);
         }
@@ -392,13 +411,14 @@
             addAttribute(atts, "width", Integer.toString(rect.width));
             addAttribute(atts, "height", Integer.toString(rect.height));
             addForeignAttributes(atts);
+            addStructurePointerAttribute(atts);
             handler.element(EL_IMAGE, atts);
         } catch (SAXException e) {
             throw new IFException("SAX error in startGroup()", e);
         }
     }
 
-    private void addForeignAttributes(AttributesImpl atts) {
+    private void addForeignAttributes(AttributesImpl atts) throws SAXException {
         Map foreignAttributes = getContext().getForeignAttributes();
         if (!foreignAttributes.isEmpty()) {
             Iterator iter = foreignAttributes.entrySet().iterator();
@@ -418,6 +438,7 @@
             addAttribute(atts, "width", Integer.toString(rect.width));
             addAttribute(atts, "height", Integer.toString(rect.height));
             addForeignAttributes(atts);
+            addStructurePointerAttribute(atts);
             handler.startElement(EL_IMAGE, atts);
             new DOM2SAX(handler).writeDocument(doc, true);
             handler.endElement(EL_IMAGE);
@@ -531,6 +552,7 @@
             if (dx != null) {
                 addAttribute(atts, "dx", IFUtil.toString(dx));
             }
+            addStructurePointerAttribute(atts);
             handler.startElement(EL_TEXT, atts);
             char[] chars = text.toCharArray();
             handler.characters(chars, 0, chars.length);
@@ -617,7 +639,8 @@
     }
 
     private void addAttribute(AttributesImpl atts,
-            org.apache.xmlgraphics.util.QName attribute, String value) {
+            org.apache.xmlgraphics.util.QName attribute, String value) throws SAXException {
+        handler.startPrefixMapping(attribute.getPrefix(), attribute.getNamespaceURI());
         XMLUtil.addAttribute(atts, attribute, value);
     }
 
@@ -625,6 +648,13 @@
         XMLUtil.addAttribute(atts, localName, value);
     }
 
+    private void addStructurePointerAttribute(AttributesImpl atts) {
+        String ptr = getContext().getStructurePointer();
+        if (ptr != null) {
+            addAttribute(atts, "ptr", ptr);
+        }
+    }
+
     // ---=== IFDocumentNavigationHandler ===---
 
     private Map incompleteActions = new java.util.HashMap();
@@ -696,6 +726,9 @@
         AttributesImpl atts = new AttributesImpl();
         atts.addAttribute(null, "rect", "rect",
                 XMLConstants.CDATA, IFUtil.toString(link.getTargetRect()));
+        if (getUserAgent().isAccessibilityEnabled()) {
+            addAttribute(atts, "ptr", link.getAction().getStructurePointer());
+        }
         try {
             handler.startElement(DocumentNavigationExtensionConstants.LINK, atts);
             serializeXMLizable(link.getAction());
Index: src/java/org/apache/fop/render/intermediate/IFConstants.java
===================================================================
--- src/java/org/apache/fop/render/intermediate/IFConstants.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/intermediate/IFConstants.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -50,4 +50,6 @@
     String EL_BORDER_RECT = "border-rect";
     String EL_FONT = "font";
     String EL_TEXT = "text";
+    /** Parent element of the logical structure tree. */
+    String EL_STRUCTURE_TREE = "structure-tree";
 }
Index: src/java/org/apache/fop/render/bitmap/BitmapRendererEventProducer.xml
===================================================================
--- src/java/org/apache/fop/render/bitmap/BitmapRendererEventProducer.xml (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/bitmap/BitmapRendererEventProducer.xml (.../branches/Temp_Accessibility) (revision 828760)
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<catalogue xml:lang="en">
+<?xml version="1.0" encoding="UTF-8"?><catalogue xml:lang="en">
   <message key="org.apache.fop.render.bitmap.BitmapRendererEventProducer.stoppingAfterFirstPageNoFilename">No filename information available. Stopping early after the first page.</message>
   <message key="org.apache.fop.render.bitmap.BitmapRendererEventProducer.stoppingAfterFirstPageNoMultiWriter">Image writer does not support multiple images. Only the first page has been produced.</message>
   <message key="org.apache.fop.render.bitmap.BitmapRendererEventProducer.noImageWriterFound">Could not get an ImageWriter to produce "{mime}". The most likely explanation for this is a class loading problem.</message>
Index: src/java/org/apache/fop/render/pcl/PCLEventProducer.xml
===================================================================
--- src/java/org/apache/fop/render/pcl/PCLEventProducer.xml (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/pcl/PCLEventProducer.xml (.../branches/Temp_Accessibility) (revision 828760)
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<catalogue xml:lang="en">
+<?xml version="1.0" encoding="UTF-8"?><catalogue xml:lang="en">
   <message key="org.apache.fop.render.pcl.PCLEventProducer.paperTypeUnavailable">Paper type ({pageWidth} x {pageHeight} mpt) could not be determined. Falling back to: {fallbackPaper}</message>
 </catalogue>

Property changes on: src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java:r699793-824832


Property changes on: src/java/org/apache/fop/render/pcl/PCLDocumentHandlerMaker.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLDocumentHandlerMaker.java:r699793-824832

Index: src/java/org/apache/fop/render/txt/TXTRenderer.java
===================================================================
--- src/java/org/apache/fop/render/txt/TXTRenderer.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/txt/TXTRenderer.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -28,6 +28,8 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.xmlgraphics.util.UnitConv;
+
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.area.Area;
 import org.apache.fop.area.CTM;
@@ -37,7 +39,6 @@
 import org.apache.fop.render.AbstractPathOrientedRenderer;
 import org.apache.fop.render.txt.border.AbstractBorderElement;
 import org.apache.fop.render.txt.border.BorderManager;
-import org.apache.xmlgraphics.util.UnitConv;
 
 /**
  * Renderer that renders areas to plain text.
Index: src/java/org/apache/fop/render/ps/PSEventProducer.xml
===================================================================
--- src/java/org/apache/fop/render/ps/PSEventProducer.xml (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/ps/PSEventProducer.xml (.../branches/Temp_Accessibility) (revision 828760)
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<catalogue xml:lang="en">
+<?xml version="1.0" encoding="UTF-8"?><catalogue xml:lang="en">
   <message key="org.apache.fop.render.ps.PSEventProducer.postscriptDictionaryParseError">Failed to parse dictionary string. Reason: {e}, content = "{content}"</message>
 </catalogue>

Property changes on: src/java/org/apache/fop/render/ImageHandlerRegistry.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFImageHandlerRegistry.java:r603620-680380


Property changes on: src/java/org/apache/fop/render/AbstractImageHandlerGraphics2D.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java:r603620-680380


Property changes on: src/java/org/apache/fop/render/ImageHandlerBase.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/branches/fop-0_95/src/java/org/apache/fop/render/ImageHandler.java:r684572,688085,688696
   Merged /xmlgraphics/fop/branches/Temp_AFPGOCAResources/src/java/org/apache/fop/render/ImageHandler.java:r630874-721418

Index: src/java/org/apache/fop/render/AbstractRendererConfigurator.java
===================================================================
--- src/java/org/apache/fop/render/AbstractRendererConfigurator.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/AbstractRendererConfigurator.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -20,6 +20,7 @@
 package org.apache.fop.render;
 
 import org.apache.avalon.framework.configuration.Configuration;
+
 import org.apache.fop.apps.FOUserAgent;
 
 /**
@@ -29,7 +30,7 @@
 public abstract class AbstractRendererConfigurator extends AbstractConfigurator {
 
     private static final String TYPE = "renderer";
-    
+
     /**
      * Default constructor
      * @param userAgent user agent
@@ -55,7 +56,7 @@
     protected Configuration getRendererConfig(String mimeType) {
         return super.getConfig(mimeType);
     }
-    
+
     /**
      * {@inheritDoc}
      */
Index: src/java/org/apache/fop/render/xml/XMLRenderer.java
===================================================================
--- src/java/org/apache/fop/render/xml/XMLRenderer.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/xml/XMLRenderer.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -34,7 +34,8 @@
 import javax.xml.transform.stream.StreamResult;
 
 import org.w3c.dom.Document;
-
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 import org.xml.sax.SAXException;
 
 import org.apache.xmlgraphics.util.QName;
@@ -86,6 +87,7 @@
 import org.apache.fop.render.RendererContext;
 import org.apache.fop.render.XMLHandler;
 import org.apache.fop.util.ColorUtil;
+import org.apache.fop.util.DOM2SAX;
 
 /**
  * Renderer that renders areas to XML for debugging purposes.
@@ -105,6 +107,8 @@
     /** If not null, the XMLRenderer will mimic another renderer by using its font setup. */
     protected Renderer mimic;
 
+    private int pageSequenceIndex;
+
     /**
      * Creates a new XML renderer.
      */
@@ -440,6 +444,20 @@
         }
         transferForeignObjects(pageSequence);
         startElement("pageSequence", atts);
+        if (this.getUserAgent().isAccessibilityEnabled()) {
+            String structureTreeElement = "structureTree";
+            startElement(structureTreeElement);
+            NodeList nodes = getUserAgent().getStructureTree().getPageSequence(pageSequenceIndex++);
+            for (int i = 0, n = nodes.getLength(); i < n; i++) {
+                Node node = nodes.item(i);
+                try {
+                    new DOM2SAX(handler).writeFragment(node);
+                } catch (SAXException e) {
+                    handleSAXException(e);
+                }
+            }
+            endElement(structureTreeElement);
+        }
         handleExtensionAttachments(pageSequence.getExtensionAttachments());
         LineArea seqTitle = pageSequence.getTitle();
         if (seqTitle != null) {
Index: src/java/org/apache/fop/render/afp/AFPEventProducer.xml
===================================================================
--- src/java/org/apache/fop/render/afp/AFPEventProducer.xml (.../trunk) (revision 0)
+++ src/java/org/apache/fop/render/afp/AFPEventProducer.xml (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><catalogue xml:lang="en"/>

Property changes on: src/java/org/apache/fop/render/afp/AFPEventProducer.xml
___________________________________________________________________
Added: svn:eol-style
   + native
Added: svn:keywords
   + Id

Index: src/java/org/apache/fop/render/pdf/PDFRenderer.java
===================================================================
--- src/java/org/apache/fop/render/pdf/PDFRenderer.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/pdf/PDFRenderer.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -31,8 +31,12 @@
 import java.io.OutputStream;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
 import org.apache.xmlgraphics.image.loader.ImageException;
 import org.apache.xmlgraphics.image.loader.ImageFlavor;
 import org.apache.xmlgraphics.image.loader.ImageInfo;
@@ -61,6 +65,7 @@
 import org.apache.fop.area.inline.Leader;
 import org.apache.fop.area.inline.SpaceArea;
 import org.apache.fop.area.inline.TextArea;
+import org.apache.fop.area.inline.Viewport;
 import org.apache.fop.area.inline.WordArea;
 import org.apache.fop.datatypes.URISpecification;
 import org.apache.fop.events.ResourceEventProducer;
@@ -91,9 +96,11 @@
 import org.apache.fop.render.AbstractPathOrientedRenderer;
 import org.apache.fop.render.Graphics2DAdapter;
 import org.apache.fop.render.RendererContext;
+import org.apache.fop.render.pdf.PDFLogicalStructureHandler.MarkedContentInfo;
 import org.apache.fop.traits.RuleStyle;
 import org.apache.fop.util.AbstractPaintingState;
 import org.apache.fop.util.CharUtilities;
+import org.apache.fop.util.XMLUtil;
 import org.apache.fop.util.AbstractPaintingState.AbstractData;
 
 /**
@@ -127,7 +134,7 @@
      * this is used for prepared pages that cannot be immediately
      * rendered
      */
-    protected Map pages = null;
+    private Map pages;
 
     /**
      * Maps unique PageViewport key to PDF page reference
@@ -193,7 +200,15 @@
     /** Image handler registry */
     private final PDFImageHandlerRegistry imageHandlerRegistry = new PDFImageHandlerRegistry();
 
+    private boolean accessEnabled;
 
+    private PDFLogicalStructureHandler logicalStructureHandler;
+
+    private int pageSequenceIndex;
+
+    /** Reference in the structure tree to the image being rendered. */
+    private String imageReference;
+
     /**
      * create the PDF renderer
      */
@@ -204,6 +219,7 @@
     public void setUserAgent(FOUserAgent agent) {
         super.setUserAgent(agent);
         this.pdfUtil = new PDFRenderingUtil(getUserAgent());
+        accessEnabled = agent.isAccessibilityEnabled();
     }
 
     PDFRenderingUtil getPDFUtil() {
@@ -225,6 +241,10 @@
         }
         ostream = stream;
         this.pdfDoc = pdfUtil.setupPDFDocument(stream);
+        if (accessEnabled) {
+            pdfDoc.getRoot().makeTagged();
+            logicalStructureHandler = new PDFLogicalStructureHandler(pdfDoc);
+        }
     }
 
     /**
@@ -274,8 +294,7 @@
      * {@inheritDoc}
      */
     public boolean supportsOutOfOrder() {
-        //return false;
-        return true;
+        return !accessEnabled;
     }
 
     /**
@@ -394,17 +413,24 @@
                 info.setTitle(str);
             }
         }
+        Locale language = null;
         if (pageSequence.getLanguage() != null) {
             String lang = pageSequence.getLanguage();
             String country = pageSequence.getCountry();
-            String langCode = lang + (country != null ? "-" + country : "");
+            if (lang != null) {
+                language = (country == null) ? new Locale(lang) : new Locale(lang, country);
+            }
             if (pdfDoc.getRoot().getLanguage() == null) {
                 //Only set if not set already (first non-null is used)
                 //Note: No checking is performed whether the values are valid!
-                pdfDoc.getRoot().setLanguage(langCode);
+                pdfDoc.getRoot().setLanguage(XMLUtil.toRFC3066(language));
             }
         }
         pdfUtil.generateDefaultXMPMetadata();
+        if (accessEnabled) {
+            NodeList nodes = getUserAgent().getStructureTree().getPageSequence(pageSequenceIndex++);
+            logicalStructureHandler.processStructureTree(nodes, language);
+        }
     }
 
     /**
@@ -457,6 +483,10 @@
         }
         currentPageRef = currentPage.referencePDF();
 
+        if (accessEnabled) {
+            logicalStructureHandler.startPage(currentPage);
+        }
+
         Rectangle bounds = page.getViewArea();
         pageHeight = bounds.height;
 
@@ -474,6 +504,10 @@
 
         super.renderPage(page);
 
+        if (accessEnabled) {
+            logicalStructureHandler.endPage();
+        }
+
         this.pdfDoc.registerObject(generator.getStream());
         currentPage.setContents(generator.getStream());
         PDFAnnotList annots = currentPage.getAnnotations();
@@ -903,11 +937,22 @@
                          + pdfDoc.getProfile());
             } else if (action != null) {
                 PDFLink pdfLink = factory.makeLink(ipRect, action);
+                if (accessEnabled) {
+                    String ptr = (String) ip.getTrait(Trait.PTR);
+                    logicalStructureHandler.addLinkContentItem(pdfLink, ptr);
+                }
                 currentPage.addAnnotation(pdfLink);
             }
         }
     }
 
+    /** {@inheritDoc} */
+    public void renderViewport(Viewport viewport) {
+        imageReference = (String) viewport.getTrait(Trait.PTR);
+        super.renderViewport(viewport);
+        imageReference = null;
+    }
+
     private Typeface getTypeface(String fontName) {
         Typeface tf = (Typeface) fontInfo.getFonts().get(fontName);
         if (tf instanceof LazyFont) {
@@ -922,7 +967,16 @@
         Color ct = (Color) text.getTrait(Trait.COLOR);
         updateColor(ct, true);
 
-        beginTextObject();
+        if (accessEnabled) {
+            String ptr = (String) text.getTrait(Trait.PTR);
+            MarkedContentInfo mci = logicalStructureHandler.addTextContentItem(ptr);
+            if (generator.getTextUtil().isInTextObject()) {
+                generator.separateTextElements(mci.tag, mci.mcid);
+            }
+            generator.beginTextObject(mci.tag, mci.mcid);
+        } else {
+            beginTextObject();
+        }
 
         String fontName = getInternalFontNameForArea(text);
         int size = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue();
@@ -1178,13 +1232,22 @@
      * @param xobj the image XObject
      */
     public void placeImage(float x, float y, float w, float h, PDFXObject xobj) {
-        saveGraphicsState();
+        if (accessEnabled) {
+            MarkedContentInfo mci = logicalStructureHandler.addImageContentItem(imageReference);
+            generator.saveGraphicsState(mci.tag, mci.mcid);
+        } else {
+            saveGraphicsState();
+        }
         generator.add(format(w) + " 0 0 "
                           + format(-h) + " "
                           + format(currentIPPosition / 1000f + x) + " "
                           + format(currentBPPosition / 1000f + h + y)
                           + " cm\n" + xobj.getName() + " Do\n");
-        restoreGraphicsState();
+        if (accessEnabled) {
+            generator.restoreGraphicsStateAccess();
+        } else {
+            restoreGraphicsState();
+        }
     }
 
     /** {@inheritDoc} */
@@ -1205,6 +1268,18 @@
         return context;
     }
 
+    /** {@inheritDoc} */
+    public void renderDocument(Document doc, String ns, Rectangle2D pos, Map foreignAttributes) {
+        if (accessEnabled) {
+            MarkedContentInfo mci = logicalStructureHandler.addImageContentItem(imageReference);
+            generator.beginMarkedContentSequence(mci.tag, mci.mcid);
+        }
+        super.renderDocument(doc, ns, pos, foreignAttributes);
+        if (accessEnabled) {
+            generator.endMarkedContentSequence();
+        }
+    }
+
     /**
      * Render leader area.
      * This renders a leader area which is an area with a rule.
@@ -1272,5 +1347,9 @@
     public void setEncryptionParams(PDFEncryptionParams encryptionParams) {
         this.pdfUtil.setEncryptionParams(encryptionParams);
     }
+
+    MarkedContentInfo addCurrentImageToStructureTree() {
+        return logicalStructureHandler.addImageContentItem(imageReference);
+    }
 }
 
Index: src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java
===================================================================
--- src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -37,6 +37,7 @@
 import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter;
 import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema;
 
+import org.apache.fop.accessibility.Accessibility;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fo.extensions.xmp.XMPMetadata;
 import org.apache.fop.pdf.PDFAMode;
@@ -109,7 +110,7 @@
 
     private void initialize() {
         PDFEncryptionParams params
-        = (PDFEncryptionParams)userAgent.getRendererOptions().get(ENCRYPTION_PARAMS);
+                = (PDFEncryptionParams)userAgent.getRendererOptions().get(ENCRYPTION_PARAMS);
         if (params != null) {
             this.encryptionParams = params; //overwrite if available
         }
@@ -161,6 +162,10 @@
         if (s != null) {
             this.pdfAMode = PDFAMode.valueOf(s);
         }
+        if (this.pdfAMode.isPDFA1LevelA()) {
+            //Enable accessibility if PDF/A-1a is enabled because it requires tagged PDF.
+            userAgent.getRendererOptions().put(Accessibility.ACCESSIBILITY, Boolean.TRUE);
+        }
         s = (String)userAgent.getRendererOptions().get(PDF_X_MODE);
         if (s != null) {
             this.pdfXMode = PDFXMode.valueOf(s);
Index: src/java/org/apache/fop/render/pdf/PDFRenderingContext.java
===================================================================
--- src/java/org/apache/fop/render/pdf/PDFRenderingContext.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/pdf/PDFRenderingContext.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -25,6 +25,7 @@
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.pdf.PDFPage;
 import org.apache.fop.render.AbstractRenderingContext;
+import org.apache.fop.render.pdf.PDFLogicalStructureHandler.MarkedContentInfo;
 
 /**
  * Rendering context for PDF production.
@@ -34,6 +35,7 @@
     private PDFContentGenerator generator;
     private FontInfo fontInfo;
     private PDFPage page;
+    private MarkedContentInfo mci;
 
     /**
      * Main constructor.
@@ -79,4 +81,11 @@
         return this.fontInfo;
     }
 
+    void setMarkedContentInfo(MarkedContentInfo mci) {
+        this.mci = mci;
+    }
+
+    MarkedContentInfo getMarkedContentInfo() {
+        return mci;
+    }
 }
Index: src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java
===================================================================
--- src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java (.../trunk) (revision 0)
+++ src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,150 @@
+/*
+ * 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.render.pdf;
+
+import java.util.Map;
+
+import org.apache.fop.pdf.PDFName;
+import org.apache.fop.pdf.PDFObject;
+import org.apache.fop.pdf.PDFStructElem;
+
+/**
+ * This class provides the standard mappings from Formatting Objects to PDF structure types.
+ */
+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");
+
+        PDFName st = new PDFName("Div");
+        addMapping("block-container",           st);
+        addMapping("inline-container",          st);
+        addMapping("table-and-caption",         st);
+        addMapping("float",                     st);
+
+        st = new PDFName("Span");
+        addMapping("inline",                    st);
+        addMapping("wrapper",                   st);
+        addMapping("character",                 st);
+
+        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");
+        addMapping("table",                     "Table");
+        addMapping("table-body",                "TBody");
+        addMapping("table-header",              THEAD);
+        addMapping("table-footer",              TFOOT);
+        addMapping("table-row",                 "TR");
+        addMapping("table-cell",                new TableCellMapper());
+
+        addMapping("list-block",                "L");
+        addMapping("list-item",                 "LI");
+        addMapping("list-item-label",           "Lbl");
+        addMapping("list-item-body",            "LBody");
+
+        addMapping("basic-link",                "Link");
+        addMapping("footnote",                  "Note");
+        addMapping("footnote-body",             "Sect");
+        addMapping("marker",                    "Private");
+    }
+
+    private static void addMapping(String fo, String pdfName) {
+        addMapping(fo, new PDFName(pdfName));
+    }
+
+    private static void addMapping(String fo, PDFName pdfName) {
+        addMapping(fo, new SimpleMapper(pdfName));
+    }
+
+    private static void addMapping(String fo, Mapper mapper) {
+        STANDARD_MAPPINGS.put(fo, mapper);
+    }
+
+    /**
+     * Maps a Formatting Object to a PDFName representing the associated structure type.
+     * @param fo the formatting object's local name
+     * @param parent the parent of the structure element to be mapped
+     * @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);
+        if (mapper != null) {
+            return mapper.getStructureType(parent);
+        } else {
+            return NON_STRUCT;
+        }
+    }
+
+    private interface Mapper {
+        PDFName getStructureType(PDFObject parent);
+    }
+
+    private static class SimpleMapper implements Mapper {
+
+        private PDFName structureType;
+
+        public SimpleMapper(PDFName structureType) {
+            this.structureType = structureType;
+        }
+
+        public PDFName getStructureType(PDFObject parent) {
+            return structureType;
+        }
+
+    }
+
+    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.
+            if (THEAD.equals(grandParent.getStructureType())) {
+               return TH;
+            } else {
+               return TD;
+            }
+        }
+
+    }
+
+    private FOToPDFRoleMap() { }
+}

Property changes on: src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java
___________________________________________________________________
Added: svn:eol-style
   + native
Added: svn:keywords
   + Id

Index: src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java
===================================================================
--- src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java (.../trunk) (revision 0)
+++ src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,299 @@
+/*
+ * 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.render.pdf;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.apache.fop.fo.extensions.ExtensionElementMapping;
+import org.apache.fop.fo.extensions.InternalElementMapping;
+import org.apache.fop.pdf.PDFArray;
+import org.apache.fop.pdf.PDFDictionary;
+import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.pdf.PDFLink;
+import org.apache.fop.pdf.PDFName;
+import org.apache.fop.pdf.PDFPage;
+import org.apache.fop.pdf.PDFParentTree;
+import org.apache.fop.pdf.PDFStructElem;
+import org.apache.fop.pdf.PDFStructTreeRoot;
+
+
+/**
+ * Handles the creation of the logical structure in the PDF document.
+ */
+class PDFLogicalStructureHandler {
+
+    private static final PDFName MCR = new PDFName("MCR");
+
+    private static final PDFName OBJR = new PDFName("OBJR");
+
+    private static final MarkedContentInfo ARTIFACT = new MarkedContentInfo(null, -1, null);
+
+    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;
+
+    private PDFPage currentPage;
+
+    /**
+     * The array of references, from marked-content sequences in the current
+     * page, to their parent structure elements. This will be a value in the
+     * structure parent tree, whose corresponding key will be the page's
+     * StructParents entry.
+     */
+    private PDFArray pageParentTreeArray;
+
+    private PDFStructElem rootStructureElement;
+
+    /**
+     * Class providing the necessary information for bracketing content
+     * associated to a structure element as a marked-content sequence.
+     */
+    static final class MarkedContentInfo {
+
+        /**
+         * A value that can be used for the tag operand of a marked-content
+         * operator. This is the structure type of the corresponding structure
+         * element.
+         */
+        final String tag;
+
+        /**
+         * The value for the MCID entry of the marked-content sequence's property list.
+         */
+        final int mcid;
+
+        private final PDFStructElem parent;
+
+        private MarkedContentInfo(String tag, int mcid, PDFStructElem parent) {
+            this.tag = tag;
+            this.mcid = mcid;
+            this.parent = parent;
+        }
+    }
+
+    /**
+     * Creates a new instance for handling the logical structure of the given document.
+     *
+     * @param pdfDoc a document
+     */
+    PDFLogicalStructureHandler(PDFDocument pdfDoc) {
+        this.pdfDoc = pdfDoc;
+        PDFStructTreeRoot structTreeRoot = pdfDoc.getFactory().makeStructTreeRoot(parentTree);
+        rootStructureElement = pdfDoc.getFactory().makeStructureElement(
+                FOToPDFRoleMap.mapFormattingObject("root", structTreeRoot), structTreeRoot);
+        structTreeRoot.addKid(rootStructureElement);
+    }
+
+    /**
+     * Converts the given structure tree into PDF.
+     *
+     * @param structureTree the structure tree of the current page sequence
+     * @param language language set on the page sequence
+     */
+    void processStructureTree(NodeList structureTree, Locale language) {
+        pdfDoc.enforceLanguageOnRoot();
+        PDFStructElem structElemPart = pdfDoc.getFactory().makeStructureElement(
+                FOToPDFRoleMap.mapFormattingObject("page-sequence", rootStructureElement),
+                rootStructureElement);
+        rootStructureElement.addKid(structElemPart);
+        if (language != null) {
+            structElemPart.setLanguage(language);
+        }
+
+        for (int i = 0, n = structureTree.getLength(); i < n; i++) {
+            Node node = structureTree.item(i);
+            assert node.getLocalName().equals("flow")
+                    || node.getLocalName().equals("static-content");
+            PDFStructElem structElemSect = pdfDoc.getFactory().makeStructureElement(
+                    FOToPDFRoleMap.mapFormattingObject(node.getLocalName(), structElemPart),
+                    structElemPart);
+            structElemPart.addKid(structElemSect);
+            NodeList childNodes = node.getChildNodes();
+            for (int j = 0, m = childNodes.getLength(); j < m; j++) {
+                processNode(childNodes.item(j), structElemSect, true);
+            }
+        }
+    }
+
+    private void processNode(Node node, PDFStructElem parent, boolean addKid) {
+        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);
+        // 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);
+        }
+        if (nodeName.equals("external-graphic") || nodeName.equals("instream-foreign-object")) {
+            Node altTextNode = node.getAttributes().getNamedItemNS(
+                    ExtensionElementMapping.URI, "alt-text");
+            if (altTextNode != null) {
+                structElem.put("Alt", altTextNode.getNodeValue());
+            } else {
+                structElem.put("Alt", "No alternate text specified");
+            }
+        }
+        structTreeMap.put(ptr, structElem);
+        NodeList nodes = node.getChildNodes();
+        for (int i = 0, n = nodes.getLength(); i < n; i++) {
+            processNode(nodes.item(i), structElem, false);
+        }
+    }
+
+    private int getNextParentTreeKey() {
+        return parentTreeKey++;
+    }
+
+    /**
+     * Receive notification of the beginning of a new page.
+     *
+     * @param page the page that will be rendered in PDF
+     */
+    void startPage(PDFPage page) {
+        currentPage = page;
+        currentPage.setStructParents(getNextParentTreeKey());
+        pageParentTreeArray = new PDFArray();
+    }
+
+    /**
+     * Receive notification of the end of the current page.
+     */
+    void endPage() {
+        // TODO
+        // Values in a number tree must be indirect references to the PDF
+        // objects associated to the keys. To enforce that the array is
+        // registered to the PDF document. Unfortunately that can't be done
+        // earlier since a call to PDFContentGenerator.flushPDFDoc can be made
+        // before the array is complete, which would result in only part of it
+        // being output to the PDF.
+        // This should really be handled by PDFNumsArray
+        pdfDoc.registerObject(pageParentTreeArray);
+        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);
+        }
+    }
+
+    /**
+     * 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
+     * @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 <code>null</code>. The content
+     * must then be treated as an artifact.
+     */
+    MarkedContentInfo addTextContentItem(String structurePointer) {
+        MarkedContentInfo mci = addToParentTree(structurePointer);
+        if (mci != ARTIFACT) {
+            PDFDictionary contentItem = new PDFDictionary();
+            contentItem.put("Type", MCR);
+            contentItem.put("Pg", this.currentPage);
+            contentItem.put("MCID", mci.mcid);
+            mci.parent.addKid(contentItem);
+        }
+        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
+     * @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 <code>null</code>. The image
+     * must then be treated as an artifact.
+     */
+    MarkedContentInfo addImageContentItem(String structurePointer) {
+        MarkedContentInfo mci = addToParentTree(structurePointer);
+        if (mci != ARTIFACT) {
+            mci.parent.setMCIDKid(mci.mcid);
+            mci.parent.setPage(this.currentPage);
+        }
+        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
+     */
+    void addLinkContentItem(PDFLink link, String structurePointer) {
+        int structParent = getNextParentTreeKey();
+        link.setStructParent(structParent);
+        parentTree.getNums().put(structParent, link);
+        PDFDictionary contentItem = new PDFDictionary();
+        contentItem.put("Type", OBJR);
+        contentItem.put("Pg", this.currentPage);
+        contentItem.put("Obj", link);
+        PDFStructElem parent = (PDFStructElem) structTreeMap.get(structurePointer);
+        parent.addKid(contentItem);
+    }
+
+}

Property changes on: src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java
___________________________________________________________________
Added: svn:eol-style
   + native
Added: svn:keywords
   + Revision Id

Index: src/java/org/apache/fop/render/pdf/PDFImageHandlerRenderedImage.java
===================================================================
--- src/java/org/apache/fop/render/pdf/PDFImageHandlerRenderedImage.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/pdf/PDFImageHandlerRenderedImage.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -34,6 +34,7 @@
 import org.apache.fop.render.ImageHandler;
 import org.apache.fop.render.RendererContext;
 import org.apache.fop.render.RenderingContext;
+import org.apache.fop.render.pdf.PDFLogicalStructureHandler.MarkedContentInfo;
 
 /**
  * Image handler implementation which handles RenderedImage instances for PDF output.
@@ -83,7 +84,12 @@
         float y = (float)pos.getY() / 1000f;
         float w = (float)pos.getWidth() / 1000f;
         float h = (float)pos.getHeight() / 1000f;
-        generator.placeImage(x, y, w, h, xobj);
+        if (context.getUserAgent().isAccessibilityEnabled()) {
+            MarkedContentInfo mci = pdfContext.getMarkedContentInfo();
+            generator.placeImage(x, y, w, h, xobj, mci.tag, mci.mcid);
+        } else {
+            generator.placeImage(x, y, w, h, xobj);
+        }
     }
 
     /** {@inheritDoc} */
Index: src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java
===================================================================
--- src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -40,6 +40,7 @@
 import org.apache.fop.image.loader.batik.BatikImageFlavors;
 import org.apache.fop.render.ImageHandler;
 import org.apache.fop.render.RenderingContext;
+import org.apache.fop.render.pdf.PDFLogicalStructureHandler.MarkedContentInfo;
 import org.apache.fop.svg.PDFAElementBridge;
 import org.apache.fop.svg.PDFBridgeContext;
 import org.apache.fop.svg.PDFGraphics2D;
@@ -101,8 +102,8 @@
         float w = (float)ctx.getDocumentSize().getWidth() * 1000f;
         float h = (float)ctx.getDocumentSize().getHeight() * 1000f;
 
-        float sx = pos.width / (float)w;
-        float sy = pos.height / (float)h;
+        float sx = pos.width / w;
+        float sy = pos.height / h;
 
         //Scaling and translation for the bounding box of the image
         AffineTransform scaling = new AffineTransform(
@@ -121,6 +122,10 @@
          */
         generator.comment("SVG setup");
         generator.saveGraphicsState();
+        if (context.getUserAgent().isAccessibilityEnabled()) {
+            MarkedContentInfo mci = pdfContext.getMarkedContentInfo();
+            generator.beginMarkedContentSequence(mci.tag, mci.mcid);
+        }
         generator.setColor(Color.black, false);
         generator.setColor(Color.black, true);
 
@@ -168,7 +173,11 @@
             eventProducer.svgRenderingError(this, e, image.getInfo().getOriginalURI());
         }
         generator.getState().restore();
-        generator.restoreGraphicsState();
+        if (context.getUserAgent().isAccessibilityEnabled()) {
+            generator.restoreGraphicsStateAccess();
+        } else {
+            generator.restoreGraphicsState();
+        }
         generator.comment("SVG end");
     }
 

Property changes on: src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java:r603620-680380

Index: src/java/org/apache/fop/render/pdf/PDFPainter.java
===================================================================
--- src/java/org/apache/fop/render/pdf/PDFPainter.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/pdf/PDFPainter.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -29,9 +29,6 @@
 
 import org.w3c.dom.Document;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.fonts.FontTriplet;
@@ -47,6 +44,7 @@
 import org.apache.fop.render.intermediate.IFContext;
 import org.apache.fop.render.intermediate.IFException;
 import org.apache.fop.render.intermediate.IFState;
+import org.apache.fop.render.pdf.PDFLogicalStructureHandler.MarkedContentInfo;
 import org.apache.fop.traits.BorderProps;
 import org.apache.fop.traits.RuleStyle;
 import org.apache.fop.util.CharUtilities;
@@ -56,26 +54,33 @@
  */
 public class PDFPainter extends AbstractIFPainter {
 
-    /** logging instance */
-    private static Log log = LogFactory.getLog(PDFPainter.class);
+    private final PDFDocumentHandler documentHandler;
 
-    private PDFDocumentHandler documentHandler;
-
     /** The current content generator */
     protected PDFContentGenerator generator;
 
-    private PDFBorderPainter borderPainter;
+    private final PDFBorderPainter borderPainter;
 
+    private boolean accessEnabled;
+
+    private MarkedContentInfo imageMCI;
+
+    private PDFLogicalStructureHandler logicalStructureHandler;
+
     /**
      * Default constructor.
      * @param documentHandler the parent document handler
+     * @param logicalStructureHandler the logical structure handler
      */
-    public PDFPainter(PDFDocumentHandler documentHandler) {
+    public PDFPainter(PDFDocumentHandler documentHandler,
+            PDFLogicalStructureHandler logicalStructureHandler) {
         super();
         this.documentHandler = documentHandler;
+        this.logicalStructureHandler = logicalStructureHandler;
         this.generator = documentHandler.generator;
         this.borderPainter = new PDFBorderPainter(this.generator);
         this.state = IFState.create();
+        accessEnabled = this.getUserAgent().isAccessibilityEnabled();
     }
 
     /** {@inheritDoc} */
@@ -122,22 +127,36 @@
     }
 
     /** {@inheritDoc} */
-    public void drawImage(String uri, Rectangle rect) throws IFException {
+    public void drawImage(String uri, Rectangle rect)
+            throws IFException {
         PDFXObject xobject = getPDFDoc().getXObject(uri);
         if (xobject != null) {
-            placeImage(rect, xobject);
-            return;
+            if (accessEnabled) {
+                String ptr = getContext().getStructurePointer();
+                prepareImageMCID(ptr);
+                placeImageAccess(rect, xobject);
+            } else {
+                placeImage(rect, xobject);
+            }
+        } else {
+            if (accessEnabled) {
+                String ptr = getContext().getStructurePointer();
+                prepareImageMCID(ptr);
+            }
+            drawImageUsingURI(uri, rect);
+            flushPDFDoc();
         }
+    }
 
-        drawImageUsingURI(uri, rect);
-
-        flushPDFDoc();
+    private void prepareImageMCID(String ptr) {
+        imageMCI = logicalStructureHandler.addImageContentItem(ptr);
     }
 
     /** {@inheritDoc} */
     protected RenderingContext createRenderingContext() {
         PDFRenderingContext pdfContext = new PDFRenderingContext(
                 getUserAgent(), generator, this.documentHandler.currentPage, getFontInfo());
+        pdfContext.setMarkedContentInfo(imageMCI);
         return pdfContext;
     }
 
@@ -158,11 +177,31 @@
                           + " cm " + xobj.getName() + " Do\n");
         generator.restoreGraphicsState();
     }
+    /**
+     * Places a previously registered image at a certain place on the page - Accessibility version
+     * @param x X coordinate
+     * @param y Y coordinate
+     * @param w width for image
+     * @param h height for image
+     * @param xobj the image XObject
+     */
+    private void placeImageAccess(Rectangle rect, PDFXObject xobj) {
+        generator.saveGraphicsState(imageMCI.tag, imageMCI.mcid);
+        generator.add(format(rect.width) + " 0 0 "
+                          + format(-rect.height) + " "
+                          + format(rect.x) + " "
+                          + format(rect.y + rect.height )
+                          + " cm " + xobj.getName() + " Do\n");
+        generator.restoreGraphicsStateAccess();
+    }
 
     /** {@inheritDoc} */
     public void drawImage(Document doc, Rectangle rect) throws IFException {
+        if (accessEnabled) {
+            String ptr = getContext().getStructurePointer();
+            prepareImageMCID(ptr);
+        }
         drawImageUsingDocument(doc, rect);
-
         flushPDFDoc();
     }
 
@@ -253,10 +292,22 @@
     }
 
     /** {@inheritDoc} */
-    public void drawText(int x, int y, int letterSpacing, int wordSpacing, int[] dx, String text)
+    public void drawText(int x, int y, int letterSpacing, int wordSpacing, int[] dx,
+            String text)
             throws IFException {
-        generator.updateColor(state.getTextColor(), true, null);
-        generator.beginTextObject();
+        if (accessEnabled) {
+            String ptr = getContext().getStructurePointer();
+            MarkedContentInfo mci = logicalStructureHandler.addTextContentItem(ptr);
+            if (generator.getTextUtil().isInTextObject()) {
+                generator.separateTextElements(mci.tag, mci.mcid);
+            }
+            generator.updateColor(state.getTextColor(), true, null);
+            generator.beginTextObject(mci.tag, mci.mcid);
+        } else {
+            generator.updateColor(state.getTextColor(), true, null);
+            generator.beginTextObject();
+        }
+
         FontTriplet triplet = new FontTriplet(
                 state.getFontFamily(), state.getFontStyle(), state.getFontWeight());
         //TODO Ignored: state.getFontVariant()
@@ -277,7 +328,7 @@
         PDFTextUtil textutil = generator.getTextUtil();
         textutil.updateTf(fontKey, fontSize, tf.isMultiByte());
 
-        generator.updateCharacterSpacing((float)letterSpacing / 1000f);
+        generator.updateCharacterSpacing(letterSpacing / 1000f);
 
         textutil.writeTextMatrix(new AffineTransform(1, 0, 0, -1, x / 1000f, y / 1000f));
         int l = text.length();
Index: src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java
===================================================================
--- src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -19,6 +19,7 @@
 
 package org.apache.fop.render.pdf;
 
+
 /**
  * Constants used for configuring PDF output.
  */
Index: src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java
===================================================================
--- src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -28,6 +28,8 @@
 import java.io.IOException;
 import java.util.Map;
 
+import org.w3c.dom.NodeList;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -50,6 +52,7 @@
 import org.apache.fop.render.intermediate.IFDocumentNavigationHandler;
 import org.apache.fop.render.intermediate.IFException;
 import org.apache.fop.render.intermediate.IFPainter;
+import org.apache.fop.util.XMLUtil;
 
 /**
  * {@link IFDocumentHandler} implementation that produces PDF.
@@ -59,6 +62,12 @@
     /** logging instance */
     private static Log log = LogFactory.getLog(PDFDocumentHandler.class);
 
+    private int pageSequenceIndex;
+
+    private boolean accessEnabled;
+
+    private PDFLogicalStructureHandler logicalStructureHandler;
+
     /** the PDF Document being created */
     protected PDFDocument pdfDoc;
 
@@ -86,7 +95,7 @@
     /** Used for bookmarks/outlines. */
     protected Map pageReferences = new java.util.HashMap();
 
-    private PDFDocumentNavigationHandler documentNavigationHandler
+    private final PDFDocumentNavigationHandler documentNavigationHandler
             = new PDFDocumentNavigationHandler(this);
 
     /**
@@ -97,7 +106,7 @@
 
     /** {@inheritDoc} */
     public boolean supportsPagesOutOfOrder() {
-        return true;
+        return !accessEnabled;
     }
 
     /** {@inheritDoc} */
@@ -125,11 +134,20 @@
         return this.pdfUtil;
     }
 
+    PDFLogicalStructureHandler getLogicalStructureHandler() {
+        return logicalStructureHandler;
+    }
+
     /** {@inheritDoc} */
     public void startDocument() throws IFException {
         super.startDocument();
         try {
             this.pdfDoc = pdfUtil.setupPDFDocument(this.outputStream);
+            this.accessEnabled = getUserAgent().isAccessibilityEnabled();
+            if (accessEnabled) {
+                pdfDoc.getRoot().makeTagged();
+                logicalStructureHandler = new PDFLogicalStructureHandler(pdfDoc);
+            }
         } catch (IOException e) {
             throw new IFException("I/O error in startDocument()", e);
         }
@@ -145,7 +163,6 @@
         try {
             pdfDoc.getResources().addFonts(pdfDoc, fontInfo);
             pdfDoc.outputTrailer(this.outputStream);
-
             this.pdfDoc = null;
 
             pdfResources = null;
@@ -160,7 +177,18 @@
 
     /** {@inheritDoc} */
     public void startPageSequence(String id) throws IFException {
-        //TODO page sequence title, country and language
+        //TODO page sequence title
+
+        if (this.pdfDoc.getRoot().getLanguage() == null
+                && getContext().getLanguage() != null) {
+            //No document-level language set, so we use the first page-sequence's language
+            this.pdfDoc.getRoot().setLanguage(XMLUtil.toRFC3066(getContext().getLanguage()));
+        }
+
+        if (accessEnabled) {
+            NodeList nodes = getUserAgent().getStructureTree().getPageSequence(pageSequenceIndex++);
+            logicalStructureHandler.processStructureTree(nodes, getContext().getLanguage());
+        }
     }
 
     /** {@inheritDoc} */
@@ -198,13 +226,17 @@
                 toPointAndScale(cropBox, scaleX, scaleY),
                 toPointAndScale(bleedBox, scaleX, scaleY),
                 toPointAndScale(trimBox, scaleX, scaleY));
+        if (accessEnabled) {
+            logicalStructureHandler.startPage(currentPage);
+        }
 
         pdfUtil.generatePageLabel(index, name);
 
         currentPageRef = new PageReference(currentPage, size);
         this.pageReferences.put(new Integer(index), currentPageRef);
 
-        this.generator = new PDFContentGenerator(this.pdfDoc, this.outputStream, this.currentPage);
+        this.generator = new PDFContentGenerator(this.pdfDoc, this.outputStream,
+                this.currentPage);
         // Transform the PDF's default coordinate system (0,0 at lower left) to the PDFPainter's
         AffineTransform basicPageTransform = new AffineTransform(1, 0, 0, -1, 0,
                 (scaleY * size.height) / 1000f);
@@ -221,7 +253,7 @@
 
     /** {@inheritDoc} */
     public IFPainter startPageContent() throws IFException {
-        return new PDFPainter(this);
+        return new PDFPainter(this, logicalStructureHandler);
     }
 
     /** {@inheritDoc} */
@@ -231,6 +263,9 @@
 
     /** {@inheritDoc} */
     public void endPage() throws IFException {
+        if (accessEnabled) {
+            logicalStructureHandler.endPage();
+        }
         try {
             this.documentNavigationHandler.commit();
             this.pdfDoc.registerObject(generator.getStream());
@@ -267,8 +302,8 @@
 
     static final class PageReference {
 
-        private PDFReference pageRef;
-        private Dimension pageDimension;
+        private final PDFReference pageRef;
+        private final Dimension pageDimension;
 
         private PageReference(PDFPage page, Dimension dim) {
             this.pageRef = page.makeReference();

Property changes on: src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java:r699793-824832

Index: src/java/org/apache/fop/render/pdf/PDFContentGenerator.java
===================================================================
--- src/java/org/apache/fop/render/pdf/PDFContentGenerator.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/pdf/PDFContentGenerator.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -56,6 +56,8 @@
     /** Text generation utility holding the current font status */
     protected PDFTextUtil textutil;
 
+    private boolean inMarkedContentSequence;
+    private boolean inArtifactMode;
 
     /**
      * Main constructor. Creates a new PDF stream and additional helper classes for text painting
@@ -153,7 +155,41 @@
         currentStream.add("q\n");
     }
 
+    /** {@inheritDoc} */
+    protected void saveGraphicsState(String structElemType, int sequenceNum) {
+        endTextObject();
+        currentState.save();
+        beginMarkedContentSequence(structElemType, sequenceNum);
+        currentStream.add("q\n");
+    }
+
     /**
+     * Begins a new marked content sequence (BDC or BMC). If the parameter structElemType is null,
+     * the sequenceNum is ignored and instead of a BDC with the MCID as parameter, an "Artifact"
+     * and a BMC command is generated.
+     * @param structElemType Structure Element Type
+     * @param mcid    Sequence number
+     */
+    protected void beginMarkedContentSequence(String structElemType, int mcid) {
+        assert !this.inMarkedContentSequence;
+        assert !this.inArtifactMode;
+        if (structElemType != null) {
+            currentStream.add(structElemType + " <</MCID " + String.valueOf(mcid) + ">>\n"
+                    + "BDC\n");
+        } else {
+            currentStream.add("/Artifact\nBMC\n");
+            this.inArtifactMode = true;
+        }
+        this.inMarkedContentSequence = true;
+    }
+
+    void endMarkedContentSequence() {
+        currentStream.add("EMC\n");
+        this.inMarkedContentSequence = false;
+        this.inArtifactMode = false;
+    }
+
+    /**
      * Restored the graphics state valid before the previous {@link #saveGraphicsState()}.
      * @param popState true if the state should also be popped, false if only the PDF command
      *           should be issued
@@ -166,11 +202,42 @@
         }
     }
 
-    /** {@inheritDoc} */
+    /**
+     * Same as {@link #restoreGraphicsState(boolean)}, with <code>true</code> as
+     * a parameter.
+     */
     protected void restoreGraphicsState() {
         restoreGraphicsState(true);
     }
 
+    /**
+     * Same as {@link #restoreGraphicsState()}, additionally ending the current
+     * marked content sequence if any.
+     */
+    protected void restoreGraphicsStateAccess() {
+        endTextObject();
+        currentStream.add("Q\n");
+        if (this.inMarkedContentSequence) {
+            endMarkedContentSequence();
+        }
+        currentState.restore();
+    }
+
+    /**
+     * Separates 2 text elements, ending the current marked content sequence and
+     * starting a new one.
+     *
+     * @param structElemType structure element type
+     * @param mcid sequence number
+     * @see #beginMarkedContentSequence(String, int)
+     */
+    protected void separateTextElements(String structElemType, int mcid) {
+        textutil.endTextObject();
+        endMarkedContentSequence();
+        beginMarkedContentSequence(structElemType, mcid);
+        textutil.beginTextObject();
+    }
+
     /** Indicates the beginning of a text object. */
     protected void beginTextObject() {
         if (!textutil.isInTextObject()) {
@@ -178,9 +245,27 @@
         }
     }
 
+    /**
+     * Indicates the beginning of a marked-content text object.
+     *
+     * @param structElemType structure element type
+     * @param mcid sequence number
+     * @see #beginTextObject()
+     * @see #beginMarkedContentSequence(String, int)
+     */
+    protected void beginTextObject(String structElemType, int mcid) {
+        if (!textutil.isInTextObject()) {
+            beginMarkedContentSequence(structElemType, mcid);
+            textutil.beginTextObject();
+        }
+    }
+
     /** Indicates the end of a text object. */
     protected void endTextObject() {
         if (textutil.isInTextObject()) {
+            if (this.inMarkedContentSequence) {
+                endMarkedContentSequence();
+            }
             textutil.endTextObject();
         }
     }
@@ -326,5 +411,28 @@
         restoreGraphicsState();
     }
 
+    /**
+     * Places a previously registered image at a certain place on the page,
+     * bracketing it as a marked-content sequence.
+     *
+     * @param x X coordinate
+     * @param y Y coordinate
+     * @param w width for image
+     * @param h height for image
+     * @param xobj the image XObject
+     * @param structElemType structure element type
+     * @param mcid sequence number
+     * @see #beginMarkedContentSequence(String, int)
+     */
+    public void placeImage(float x, float y, float w, float h, PDFXObject xobj,
+            String structElemType, int mcid) {
+        saveGraphicsState(structElemType, mcid);
+        add(format(w) + " 0 0 "
+                          + format(-h) + " "
+                          + format(x) + " "
+                          + format(y + h)
+                          + " cm\n" + xobj.getName() + " Do\n");
+        restoreGraphicsStateAccess();
+    }
 
 }
Index: src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java
===================================================================
--- src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -35,6 +35,7 @@
 import org.apache.fop.render.AbstractImageHandlerGraphics2D;
 import org.apache.fop.render.RendererContext;
 import org.apache.fop.render.RenderingContext;
+import org.apache.fop.render.pdf.PDFLogicalStructureHandler.MarkedContentInfo;
 import org.apache.fop.svg.PDFGraphics2D;
 
 /**
@@ -63,6 +64,9 @@
                 renderer.currentPage,
                 renderer.getFontInfo());
         Rectangle effPos = new Rectangle(origin.x + pos.x, origin.y + pos.y, pos.width, pos.height);
+        if (context.getUserAgent().isAccessibilityEnabled()) {
+            pdfContext.setMarkedContentInfo(renderer.addCurrentImageToStructureTree());
+        }
         handleImage(pdfContext, image, effPos);
         return null;
     }
@@ -87,7 +91,13 @@
         float sy = fheight / (float)imh;
 
         generator.comment("G2D start");
-        generator.saveGraphicsState();
+        boolean accessibilityEnabled = context.getUserAgent().isAccessibilityEnabled();
+        if (accessibilityEnabled) {
+            MarkedContentInfo mci = pdfContext.getMarkedContentInfo();
+            generator.saveGraphicsState(mci.tag, mci.mcid);
+        } else {
+            generator.saveGraphicsState();
+        }
         generator.updateColor(Color.black, false, null);
         generator.updateColor(Color.black, true, null);
 
@@ -115,7 +125,11 @@
         imageG2D.getGraphics2DImagePainter().paint(graphics, area);
 
         generator.add(graphics.getString());
-        generator.restoreGraphicsState();
+        if (accessibilityEnabled) {
+            generator.restoreGraphicsStateAccess();
+        } else {
+            generator.restoreGraphicsState();
+        }
         generator.comment("G2D end");
     }
 
Index: src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java
===================================================================
--- src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -47,10 +47,10 @@
  */
 public class PDFDocumentNavigationHandler implements IFDocumentNavigationHandler {
 
-    private PDFDocumentHandler documentHandler;
+    private final PDFDocumentHandler documentHandler;
 
-    private Map incompleteActions = new java.util.HashMap();
-    private Map completeActions = new java.util.HashMap();
+    private final Map incompleteActions = new java.util.HashMap();
+    private final Map completeActions = new java.util.HashMap();
 
     /**
      * Default constructor.
@@ -111,6 +111,11 @@
         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);
+            }
             documentHandler.currentPage.addAnnotation(pdfLink);
         }
     }

Property changes on: src/java/org/apache/fop/render/pdf/PDFDocumentHandlerMaker.java
___________________________________________________________________
Added: svn:mergeinfo
   Merged /xmlgraphics/fop/branches/fop-0_95/src/java/org/apache/fop/render/pdf/PDFPainterMaker.java:r684572
   Merged /xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFPainterMaker.java:r603620-685574

Index: src/java/org/apache/fop/render/pdf/PDFImageHandlerRawJPEG.java
===================================================================
--- src/java/org/apache/fop/render/pdf/PDFImageHandlerRawJPEG.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/render/pdf/PDFImageHandlerRawJPEG.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -34,6 +34,7 @@
 import org.apache.fop.render.ImageHandler;
 import org.apache.fop.render.RendererContext;
 import org.apache.fop.render.RenderingContext;
+import org.apache.fop.render.pdf.PDFLogicalStructureHandler.MarkedContentInfo;
 
 /**
  * Image handler implementation which handles raw JPEG images for PDF output.
@@ -82,7 +83,12 @@
         float y = (float)pos.getY() / 1000f;
         float w = (float)pos.getWidth() / 1000f;
         float h = (float)pos.getHeight() / 1000f;
-        generator.placeImage(x, y, w, h, xobj);
+        if (context.getUserAgent().isAccessibilityEnabled()) {
+            MarkedContentInfo mci = pdfContext.getMarkedContentInfo();
+            generator.placeImage(x, y, w, h, xobj, mci.tag, mci.mcid);
+        } else {
+            generator.placeImage(x, y, w, h, xobj);
+        }
     }
 
     /** {@inheritDoc} */
Index: src/java/org/apache/fop/layoutmgr/TraitSetter.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/TraitSetter.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/layoutmgr/TraitSetter.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -584,6 +584,17 @@
     }
 
     /**
+     * Adds the ptr trait to the area.
+     * @param area the area to set the traits on
+     * @param ptr string
+     */
+    public static void addPtr(Area area, String ptr) {
+        if (ptr != null && ptr.length() > 0) {
+            area.addTrait(Trait.PTR, ptr);
+        }
+    }
+    
+    /**
      * Sets the producer's ID as a trait on the area. This can be used to track back the
      * generating FO node.
      * @param area the area to set the traits on
Index: src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -391,6 +391,7 @@
 
         addMarkersToPage(false, isFirst(firstPos), isLast(lastPos));
 
+        TraitSetter.addPtr(curBlockArea, getBlockFO().getPtr());  // used for accessibility
         TraitSetter.addSpaceBeforeAfter(curBlockArea, layoutContext.getSpaceAdjust(),
                 effSpaceBefore, effSpaceAfter);
         flush();
Index: src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -25,10 +25,13 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+
 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;
@@ -504,12 +507,26 @@
         }
         TraitSetter.addFontTraits(textArea, font);
         textArea.addTrait(Trait.COLOR, this.foText.getColor());
-
+        TraitSetter.addPtr(textArea, getPtr()); // used for accessibility
         TraitSetter.addTextDecoration(textArea, this.foText.getTextDecoration());
 
         return textArea;
     }
 
+    /**
+     * used for accessibility
+     * @return ptr of fobj
+     */
+    private String getPtr() {
+        FObj fobj = this.parentLM.getFObj();
+        if (fobj instanceof StructurePointerPropertySet) {
+            return (((StructurePointerPropertySet) fobj).getPtr());
+        } else {
+            //No structure pointer applicable
+            return null;
+        }
+    }
+
     private void addToLetterAdjust(final int index, final int width) {
         if (this.letterAdjustArray[index] == null) {
             this.letterAdjustArray[index] = new MinOptMax(width);
Index: src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/layoutmgr/inline/AbstractGraphicsLayoutManager.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -85,6 +85,7 @@
         transferForeignAttributes(viewportArea);
 
         Viewport vp = new Viewport(viewportArea);
+        TraitSetter.addPtr(vp, fobj.getPtr());  // used for accessibility
         TraitSetter.setProducerID(vp, fobj.getId());
         vp.setIPD(imageLayout.getViewportSize().width);
         vp.setBPD(imageLayout.getViewportSize().height);
Index: src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -85,7 +85,7 @@
         text.setBaselineOffset(font.getAscender());
         TraitSetter.addFontTraits(text, font);
         text.addTrait(Trait.COLOR, fobj.getColor());
-
+        TraitSetter.addPtr(text, fobj.getPtr()); // used for accessibility
         TraitSetter.addTextDecoration(text, fobj.getTextDecoration());
 
         return text;
Index: src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -86,6 +86,7 @@
         }
         TraitSetter.setProducerID(text, node.getId());
         TraitSetter.addTextDecoration(text, node.getTextDecoration());
+        TraitSetter.addPtr(text, node.getPtr()); // used for accessibility
         return text;
     }
 
Index: src/java/org/apache/fop/layoutmgr/inline/BasicLinkLayoutManager.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/inline/BasicLinkLayoutManager.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/layoutmgr/inline/BasicLinkLayoutManager.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -19,13 +19,14 @@
 
 package org.apache.fop.layoutmgr.inline;
 
+import org.apache.fop.area.LinkResolver;
+import org.apache.fop.area.Trait;
+import org.apache.fop.area.inline.InlineArea;
 import org.apache.fop.datatypes.URISpecification;
+import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.flow.BasicLink;
-import org.apache.fop.fo.Constants;
 import org.apache.fop.layoutmgr.PageSequenceLayoutManager;
-import org.apache.fop.area.inline.InlineArea;
-import org.apache.fop.area.Trait;
-import org.apache.fop.area.LinkResolver;
+import org.apache.fop.layoutmgr.TraitSetter;
 
 /**
  * LayoutManager for the fo:basic-link formatting object
@@ -56,6 +57,7 @@
     private void setupBasicLinkArea(InlineArea area) {
         BasicLink fobj = (BasicLink) this.fobj;
         // internal destinations take precedence:
+        TraitSetter.addPtr(area, fobj.getPtr()); // used for accessibility
         if (fobj.hasInternalDestination()) {
             String idref = fobj.getInternalDestination();
             PageSequenceLayoutManager pslm = getPSLM();
Index: src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/layoutmgr/inline/AbstractPageNumberCitationLayoutManager.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -138,6 +138,7 @@
         text.setBaselineOffset(font.getAscender());
         TraitSetter.addFontTraits(text, font);
         text.addTrait(Trait.COLOR, fobj.getColor());
+        TraitSetter.addPtr(text, fobj.getPtr());   // used for accessibility
         TraitSetter.addTextDecoration(text, fobj.getTextDecoration());
     }
 
Index: src/java/org/apache/fop/accessibility/StructureTree.java
===================================================================
--- src/java/org/apache/fop/accessibility/StructureTree.java (.../trunk) (revision 0)
+++ src/java/org/apache/fop/accessibility/StructureTree.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,102 @@
+/*
+ * 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;
+
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * A reduced version of the document's FO tree, containing only its logical
+ * structure. Used by accessible output formats.
+ */
+public final class StructureTree {
+
+    private final List pageSequenceStructures = new ArrayList();
+
+    /**
+     * Package-private default constructor.
+     */
+    StructureTree() { }
+
+    private static boolean flowOrStaticContentNodes(NodeList nodes) {
+        for (int i = 0; i < nodes.getLength(); i++) {
+            Node node = nodes.item(i);
+            if (node.getNodeType() != Node.ELEMENT_NODE) {
+                return false;
+            }
+            String name = node.getLocalName();
+            if (!(name.equals("flow") || name.equals("static-content"))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    void addPageSequenceStructure(NodeList structureTree) {
+        assert flowOrStaticContentNodes(structureTree);
+        pageSequenceStructures.add(structureTree);
+    }
+
+    /**
+     * Returns the list of nodes that are the children of the given page sequence.
+     *
+     * @param index index of the page sequence, 0-based
+     * @return its children nodes
+     */
+    public NodeList getPageSequence(int index) {
+        return (NodeList) pageSequenceStructures.get(index);
+    }
+
+    /**
+     * Returns an XML-like representation of the structure trees.
+     * <p>
+     * <strong>Note:</strong> use only for debugging purpose, as this method
+     * performs non-trivial operations.
+     * </p>
+     * @return a string representation of this object
+     */
+    public String toString() {
+        try {
+            Transformer t = TransformerFactory.newInstance().newTransformer();
+            Writer str = new StringWriter();
+            for (Iterator iter = pageSequenceStructures.iterator(); iter.hasNext();) {
+                NodeList nodes = (NodeList) iter.next();
+                for (int i = 0, c = nodes.getLength(); i < c; i++) {
+                    t.transform(new DOMSource(nodes.item(i)), new StreamResult(str));
+                }
+            }
+            return str.toString();
+        } catch (Exception e) {
+            return e.toString();
+        }
+    }
+
+}

Property changes on: src/java/org/apache/fop/accessibility/StructureTree.java
___________________________________________________________________
Added: svn:keywords
   + Revision Id
Added: svn:eol-style
   + native

Index: src/java/org/apache/fop/accessibility/reduceFOTree.xsl
===================================================================
--- src/java/org/apache/fop/accessibility/reduceFOTree.xsl (.../trunk) (revision 0)
+++ src/java/org/apache/fop/accessibility/reduceFOTree.xsl (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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$ -->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  xmlns:fo="http://www.w3.org/1999/XSL/Format"
+  xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"
+  xmlns:foi="http://xmlgraphics.apache.org/fop/internal">
+
+  <xsl:output method="xml" indent="no"/>
+
+  <xsl:template name="copy">
+    <xsl:copy>
+      <xsl:apply-templates select="@*|node()"/>
+    </xsl:copy>
+  </xsl:template>
+
+  <!-- Declarations and Pagination and Layout Formatting Objects -->
+  <xsl:template match="fo:root|fo:page-sequence|fo:static-content|fo:flow">
+    <xsl:call-template name="copy"/>
+  </xsl:template>
+
+  <!-- Block-level Formatting Objects -->
+  <xsl:template match="fo:block|fo:block-container">
+    <xsl:call-template name="copy"/>
+  </xsl:template>
+
+  <!-- Inline-level Formatting Objects -->
+  <xsl:template match="fo:character|fo:inline|fo:inline-container">
+    <xsl:call-template name="copy"/>
+  </xsl:template>
+
+  <xsl:template match="fo:external-graphic|fo:instream-foreign-object">
+    <xsl:call-template name="copy"/>
+  </xsl:template>
+
+  <xsl:template match="fo:page-number|fo:page-number-citation|fo:page-number-citation-last">
+    <xsl:call-template name="copy"/>
+  </xsl:template>
+
+  <!-- Formatting Objects for Tables -->
+  <xsl:template match="fo:table-and-caption|fo:table-caption|fo:table">
+    <xsl:call-template name="copy"/>
+  </xsl:template>
+
+  <xsl:template match="fo:table-header|fo:table-footer|fo:table-body|fo:table-row|fo:table-cell">
+    <xsl:call-template name="copy"/>
+  </xsl:template>
+
+  <!-- Formatting Objects for Lists -->
+  <xsl:template match="fo:list-block|fo:list-item|fo:list-item-label|fo:list-item-body">
+    <xsl:call-template name="copy"/>
+  </xsl:template>
+
+  <!-- Dynamic Effects: Link and Multi Formatting Objects -->
+  <xsl:template match="fo:basic-link">
+    <xsl:call-template name="copy"/>
+  </xsl:template>
+
+  <!-- Out-of-Line Formatting Objects -->
+  <xsl:template match="fo:float|fo:footnote|fo:footnote-body">
+    <xsl:call-template name="copy"/>
+  </xsl:template>
+
+  <!-- Other Formatting Objects -->
+  <xsl:template match="fo:wrapper|fo:marker">
+    <xsl:call-template name="copy"/>
+  </xsl:template>
+
+
+  <!-- Discard descendants of fo:leader -->
+  <xsl:template match="fo:leader"/>
+      
+
+  <!-- Keep foi:ptr and fox:alt-text attributes, discard everything else -->
+  <xsl:template match="@foi:ptr|@fox:alt-text">
+    <xsl:copy-of select="."/>
+  </xsl:template>
+
+  <xsl:template match="@*"/>
+
+
+  <!-- Discard text -->
+  <xsl:template match="text()"/>
+
+</xsl:stylesheet>

Property changes on: src/java/org/apache/fop/accessibility/reduceFOTree.xsl
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: src/java/org/apache/fop/accessibility/addPtr.xsl
===================================================================
--- src/java/org/apache/fop/accessibility/addPtr.xsl (.../trunk) (revision 0)
+++ src/java/org/apache/fop/accessibility/addPtr.xsl (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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$ -->
+<xsl:stylesheet version="1.0"
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  xmlns:fo="http://www.w3.org/1999/XSL/Format"
+  xmlns:foi="http://xmlgraphics.apache.org/fop/internal">
+
+  <xsl:template name="addPtr">
+    <xsl:copy>
+      <xsl:apply-templates select="@*"/>
+      <xsl:attribute name="foi:ptr">
+        <xsl:value-of select="generate-id()"/>
+      </xsl:attribute>
+      <xsl:apply-templates/>
+    </xsl:copy>
+  </xsl:template>
+
+  <!-- Block-level Formatting Objects -->
+  <xsl:template match="fo:block|fo:block-container">
+    <xsl:call-template name="addPtr"/>
+  </xsl:template>
+
+  <!-- Inline-level Formatting Objects -->
+  <xsl:template match="fo:character|fo:inline|fo:inline-container">
+    <xsl:call-template name="addPtr"/>
+  </xsl:template>
+
+  <xsl:template match="fo:external-graphic|fo:instream-foreign-object">
+    <xsl:call-template name="addPtr"/>
+  </xsl:template>
+
+  <xsl:template match="fo:page-number|fo:page-number-citation|fo:page-number-citation-last">
+    <xsl:call-template name="addPtr"/>
+  </xsl:template>
+
+  <!-- Formatting Objects for Tables -->
+  <xsl:template match="fo:table-and-caption|fo:table-caption|fo:table">
+    <xsl:call-template name="addPtr"/>
+  </xsl:template>
+
+  <xsl:template match="fo:table-header|fo:table-footer|fo:table-body|fo:table-row|fo:table-cell">
+    <xsl:call-template name="addPtr"/>
+  </xsl:template>
+
+  <!-- Formatting Objects for Lists -->
+  <xsl:template match="fo:list-block|fo:list-item|fo:list-item-label|fo:list-item-body">
+    <xsl:call-template name="addPtr"/>
+  </xsl:template>
+
+  <!-- Dynamic Effects: Link and Multi Formatting Objects -->
+  <xsl:template match="fo:basic-link">
+    <xsl:call-template name="addPtr"/>
+  </xsl:template>
+
+  <!-- Out-of-Line Formatting Objects -->
+  <xsl:template match="fo:float|fo:footnote|fo:footnote-body">
+    <xsl:call-template name="addPtr"/>
+  </xsl:template>
+
+  <!-- Other Formatting Objects -->
+  <xsl:template match="fo:wrapper|fo:marker">
+    <xsl:call-template name="addPtr"/>
+  </xsl:template>
+
+
+  <xsl:template match="@*|node()">
+    <xsl:copy>
+      <xsl:apply-templates select="@*|node()"/>
+    </xsl:copy>
+  </xsl:template>
+
+</xsl:stylesheet>

Property changes on: src/java/org/apache/fop/accessibility/addPtr.xsl
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: src/java/org/apache/fop/accessibility/Accessibility.java
===================================================================
--- src/java/org/apache/fop/accessibility/Accessibility.java (.../trunk) (revision 0)
+++ src/java/org/apache/fop/accessibility/Accessibility.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,87 @@
+/*
+ * 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;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamSource;
+
+import org.xml.sax.helpers.DefaultHandler;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+
+/**
+ * Helper class for FOP's accessibility features.
+ */
+public final class Accessibility {
+
+    /** Constant string for the rendering options key to enable accessibility features. */
+    public static final String ACCESSIBILITY = "accessibility";
+
+    // TODO what if the default factory is not a SAXTransformerFactory?
+    private static SAXTransformerFactory tfactory
+            = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
+
+    private static Templates addPtrTemplates;
+
+    private static Templates reduceFOTreeTemplates;
+
+    private Accessibility() { }
+
+    /**
+     * Decorates the given handler so the structure tree used for accessibility
+     * features can be branched off the main content stream.
+     * @param handler the handler to decorate
+     * @param userAgent the user agent
+     * @return the decorated handler
+     * @throws FOPException if an error occurs setting up the decoration
+     */
+    public static DefaultHandler decorateDefaultHandler(DefaultHandler handler,
+            FOUserAgent userAgent) throws FOPException {
+        try {
+            setupTemplates();
+            TransformerHandler addPtr = tfactory.newTransformerHandler(addPtrTemplates);
+            Transformer reduceFOTree = reduceFOTreeTemplates.newTransformer();
+            return new AccessibilityPreprocessor(addPtr, reduceFOTree, userAgent, handler);
+        } catch (TransformerConfigurationException e) {
+            throw new FOPException(e);
+        }
+    }
+
+    private static synchronized void setupTemplates() throws TransformerConfigurationException {
+        if (addPtrTemplates == null) {
+            addPtrTemplates = loadTemplates("addPtr.xsl");
+        }
+        if (reduceFOTreeTemplates == null) {
+            reduceFOTreeTemplates = loadTemplates("reduceFOTree.xsl");
+        }
+    }
+
+    private static Templates loadTemplates(String source) throws TransformerConfigurationException {
+        Source src = new StreamSource(Accessibility.class.getResource(source).toExternalForm());
+        return tfactory.newTemplates(src);
+    }
+
+}

Property changes on: src/java/org/apache/fop/accessibility/Accessibility.java
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: src/java/org/apache/fop/accessibility/StructureTreeBuilder.java
===================================================================
--- src/java/org/apache/fop/accessibility/StructureTreeBuilder.java (.../trunk) (revision 0)
+++ src/java/org/apache/fop/accessibility/StructureTreeBuilder.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,95 @@
+/*
+ * 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;
+
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+import org.apache.fop.util.DelegatingContentHandler;
+
+/**
+ * Helper class that re-builds a structure tree from what is stored in an
+ * intermediate XML file (IF XML or Area Tree XML).
+ */
+public final class StructureTreeBuilder {
+
+    private final SAXTransformerFactory factory;
+
+    private final StructureTree structureTree = new StructureTree();
+
+    /**
+     * Creates a new instance.
+     *
+     * @param factory a factory internally used to build the structures of page
+     * sequences
+     */
+    public StructureTreeBuilder(SAXTransformerFactory factory) {
+        this.factory = factory;
+    }
+
+    /**
+     * Returns the structure tree that will result from the parsing.
+     *
+     * @return the structure tree built by this object
+     */
+    public StructureTree getStructureTree() {
+        return structureTree;
+    }
+
+    /**
+     * Returns a ContenHandler for parsing the structure of a new page sequence.
+     * It is assumed that page sequences are being parsed in the document order.
+     *
+     * @return a handler for parsing the <structure-tree> or
+     * <structureTree> element and its descendants
+     * @throws SAXException if there is an error when creating the handler
+     */
+    public ContentHandler getHandlerForNextPageSequence() throws SAXException {
+        TransformerHandler structureTreeBuilder;
+        try {
+            structureTreeBuilder = factory.newTransformerHandler();
+        } catch (TransformerConfigurationException e) {
+            throw new SAXException(e);
+        }
+        final DOMResult domResult = new DOMResult();
+        structureTreeBuilder.setResult(domResult);
+        return new DelegatingContentHandler(structureTreeBuilder) {
+
+            public void characters(char[] ch, int start, int length) throws SAXException {
+                /*
+                 * There's no text node in the structure tree. This is just
+                 * whitespace => ignore
+                 */
+            }
+
+            public void endDocument() throws SAXException {
+                super.endDocument();
+                structureTree.addPageSequenceStructure(domResult.getNode().getFirstChild()
+                        .getChildNodes());
+            }
+        };
+    }
+
+}

Property changes on: src/java/org/apache/fop/accessibility/StructureTreeBuilder.java
___________________________________________________________________
Added: svn:keywords
   + Revision Id
Added: svn:eol-style
   + native

Index: src/java/org/apache/fop/accessibility/AccessibilityEventProducer.xml
===================================================================
--- src/java/org/apache/fop/accessibility/AccessibilityEventProducer.xml (.../trunk) (revision 0)
+++ src/java/org/apache/fop/accessibility/AccessibilityEventProducer.xml (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<catalogue xml:lang="en">
+  <message key="org.apache.fop.accessibility.AccessibilityEventProducer.noStructureTreeInXML">Accessibility is enabled but structure tree is missing in XML file. Please disable accessibility, or re-generate XML file in accessibility mode.</message>
+</catalogue>

Property changes on: src/java/org/apache/fop/accessibility/AccessibilityEventProducer.xml
___________________________________________________________________
Added: svn:keywords
   + Revision Id
Added: svn:eol-style
   + native

Index: src/java/org/apache/fop/accessibility/AccessibilityEventProducer.java
===================================================================
--- src/java/org/apache/fop/accessibility/AccessibilityEventProducer.java (.../trunk) (revision 0)
+++ src/java/org/apache/fop/accessibility/AccessibilityEventProducer.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -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;
+
+import org.apache.fop.events.EventBroadcaster;
+import org.apache.fop.events.EventProducer;
+
+/**
+ * Event producer for accessibility-related events.
+ */
+public interface AccessibilityEventProducer extends EventProducer {
+
+    /** Provider class for the event producer. */
+    public final class Provider {
+
+        private Provider() { }
+
+        /**
+         * Returns an event producer.
+         *
+         * @param broadcaster the event broadcaster to use
+         * @return the event producer
+         */
+        public static AccessibilityEventProducer get(EventBroadcaster broadcaster) {
+            return (AccessibilityEventProducer) broadcaster.getEventProducerFor(
+                    AccessibilityEventProducer.class);
+        }
+    }
+
+    /**
+     * The structure tree is missing in the XML file.
+     *
+     * @param source the event source
+     * @event.severity FATAL
+     */
+    void noStructureTreeInXML(Object source);
+}

Property changes on: src/java/org/apache/fop/accessibility/AccessibilityEventProducer.java
___________________________________________________________________
Added: svn:keywords
   + Revision Id
Added: svn:eol-style
   + native

Index: src/java/org/apache/fop/accessibility/AccessibilityPreprocessor.java
===================================================================
--- src/java/org/apache/fop/accessibility/AccessibilityPreprocessor.java (.../trunk) (revision 0)
+++ src/java/org/apache/fop/accessibility/AccessibilityPreprocessor.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,95 @@
+/*
+ * 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;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import org.apache.commons.io.output.ByteArrayOutputStream;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.util.TransformerDefaultHandler;
+
+/**
+ * This class prepares an XSL-FO document for accessibility. It adds a unique
+ * identifier to every applicable FO, then creates the structure tree, before
+ * handing the document over to the regular handler.
+ */
+class AccessibilityPreprocessor extends TransformerDefaultHandler {
+
+    private final ByteArrayOutputStream enrichedFOBuffer = new ByteArrayOutputStream();
+
+    private final Transformer reduceFOTree;
+
+    private final FOUserAgent userAgent;
+
+    private final DefaultHandler fopHandler;
+
+    public AccessibilityPreprocessor(TransformerHandler addPtr, Transformer reduceFOTree,
+            FOUserAgent userAgent, DefaultHandler fopHandler) {
+        super(addPtr);
+        this.reduceFOTree = reduceFOTree;
+        this.userAgent = userAgent;
+        this.fopHandler = fopHandler;
+        getTransformerHandler().setResult(new StreamResult(enrichedFOBuffer));
+    }
+
+    /** {@inheritDoc} */
+    public void endDocument() throws SAXException {
+        super.endDocument();
+        // do the second transform to struct
+        try {
+            //TODO this must be optimized, no buffering (ex. SAX-based tee-proxy)
+            byte[] enrichedFO = enrichedFOBuffer.toByteArray();
+            Source src = new StreamSource(new ByteArrayInputStream(enrichedFO));
+            DOMResult res = new DOMResult();
+            reduceFOTree.transform(src, res);
+            StructureTree structureTree = new StructureTree();
+            NodeList pageSequences = res.getNode().getFirstChild().getChildNodes();
+            for (int i = 0; i < pageSequences.getLength(); i++) {
+                structureTree.addPageSequenceStructure(pageSequences.item(i).getChildNodes());
+            }
+            userAgent.setStructureTree(structureTree);
+
+            SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
+            saxParserFactory.setNamespaceAware(true);
+            saxParserFactory.setValidating(false);
+            SAXParser saxParser = saxParserFactory.newSAXParser();
+            InputStream in = new ByteArrayInputStream(enrichedFO);
+            saxParser.parse(in, fopHandler);
+        } catch (Exception e) {
+            throw new SAXException(e);
+        }
+    }
+
+}

Property changes on: src/java/org/apache/fop/accessibility/AccessibilityPreprocessor.java
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Index: src/java/org/apache/fop/apps/FopFactoryConfigurator.java
===================================================================
--- src/java/org/apache/fop/apps/FopFactoryConfigurator.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/apps/FopFactoryConfigurator.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -92,6 +92,15 @@
             log.debug("Initializing FopFactory Configuration");
         }
 
+        if (cfg.getChild("accessibility", false) != null) {
+            try {
+                this.factory.setAccessibility(
+                        cfg.getChild("accessibility").getValueAsBoolean());
+            } catch (ConfigurationException e) {
+                throw new FOPException(e);
+            }
+        }
+
         // strict configuration
         if (cfg.getChild("strict-configuration", false) != null) {
             try {
Index: src/java/org/apache/fop/apps/FOUserAgent.java
===================================================================
--- src/java/org/apache/fop/apps/FOUserAgent.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/apps/FOUserAgent.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -37,6 +37,8 @@
 import org.apache.xmlgraphics.image.loader.impl.AbstractImageSessionContext;
 
 import org.apache.fop.Version;
+import org.apache.fop.accessibility.Accessibility;
+import org.apache.fop.accessibility.StructureTree;
 import org.apache.fop.events.DefaultEventBroadcaster;
 import org.apache.fop.events.Event;
 import org.apache.fop.events.EventBroadcaster;
@@ -99,6 +101,8 @@
     private boolean conserveMemoryPolicy = false;
     private EventBroadcaster eventBroadcaster = new FOPEventBroadcaster();
 
+    private StructureTree structureTree;
+
     /** Producer:  Metadata element for the system/software that produces
      * the document. (Some renderers can store this in the document.)
      */
@@ -152,6 +156,7 @@
         this.factory = factory;
         setBaseURL(factory.getBaseURL());
         setTargetResolution(factory.getTargetResolution());
+        setAccessibility(factory.isAccessibilityEnabled());
     }
 
     /** @return the associated FopFactory instance */
@@ -196,6 +201,7 @@
         return rendererOverride;
     }
 
+
     /**
      * Sets an explicit FOEventHandler instance which overrides the one
      * defined by the render type setting.
@@ -642,5 +648,49 @@
         this.conserveMemoryPolicy = conserveMemoryPolicy;
     }
 
+    /**
+     * Activates accessibility (for output formats that support it).
+     *
+     * @param accessibility <code>true</code> to enable accessibility support
+     */
+    public void setAccessibility(boolean accessibility) {
+        if (accessibility) {
+            getRendererOptions().put(Accessibility.ACCESSIBILITY, Boolean.TRUE);
+        }
+    }
+
+    /**
+     * Check if accessibility is enabled.
+     * @return true if accessibility is enabled
+     */
+    public boolean isAccessibilityEnabled() {
+        Boolean enabled = (Boolean)this.getRendererOptions().get(Accessibility.ACCESSIBILITY);
+        if (enabled != null) {
+            return enabled.booleanValue();
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Sets the document's structure tree, for use by accessible output formats.
+     *
+     * @param structureTree a simplified version of the FO tree, retaining only
+     * its logical structure
+     */
+    public void setStructureTree(StructureTree structureTree) {
+        this.structureTree = structureTree;
+    }
+
+    /**
+     * Returns the document's structure tree, for use by accessible output
+     * formats.
+     *
+     * @return a simplified version of the FO tree, retaining only its logical
+     * structure
+     */
+    public StructureTree getStructureTree() {
+        return this.structureTree;
+    }
 }
 
Index: src/java/org/apache/fop/apps/Fop.java
===================================================================
--- src/java/org/apache/fop/apps/Fop.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/apps/Fop.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -24,6 +24,7 @@
 
 import org.xml.sax.helpers.DefaultHandler;
 
+import org.apache.fop.accessibility.Accessibility;
 import org.apache.fop.fo.FOTreeBuilder;
 
 /**
@@ -110,7 +111,11 @@
         if (foTreeBuilder == null) {
             createDefaultHandler();
         }
-        return this.foTreeBuilder;
+        if (this.foUserAgent.isAccessibilityEnabled()) {
+            return Accessibility.decorateDefaultHandler(this.foTreeBuilder, foUserAgent);
+        } else {
+            return this.foTreeBuilder;
+        }
     }
 
     /**
Index: src/java/org/apache/fop/apps/FopFactory.java
===================================================================
--- src/java/org/apache/fop/apps/FopFactory.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/apps/FopFactory.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -100,6 +100,11 @@
      */
     private String base = null;
 
+    /**
+     *  Controls if accessibility is turned on or off
+     */
+    private boolean accessibility = false;
+
     /** The base URL for all hyphen URL resolutions. */
     private String hyphenBase = null;
 
@@ -185,6 +190,19 @@
     }
 
     /**
+     * Sets accessibility support.
+     *
+     * @param value <code>true</code> to enable accessibility, <code>false</code> otherwise
+     */
+    void setAccessibility(boolean value) {
+        this.accessibility = value;
+    }
+
+    boolean isAccessibilityEnabled() {
+        return accessibility;
+    }
+
+    /**
      * Returns a new {@link Fop} instance. FOP will be configured with a default user agent
      * instance.
      * <p>
Index: src/java/org/apache/fop/events/EventFormatter.xml
===================================================================
--- src/java/org/apache/fop/events/EventFormatter.xml (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/events/EventFormatter.xml (.../branches/Temp_Accessibility) (revision 828760)
@@ -105,4 +105,5 @@
   <message key="org.apache.fop.fonts.FontEventAdapter.fontSubstituted">Font "{requested}" not found. Substituting with "{effective}".</message>
   <message key="org.apache.fop.fonts.FontEventAdapter.fontLoadingErrorAtAutoDetection">Unable to load font file: {fontURL}.[ Reason: {e}]</message>
   <message key="org.apache.fop.fonts.FontEventAdapter.glyphNotAvailable">Glyph "{ch}" (0x{ch,hex}[, {ch,glyph-name}]) not available in font "{fontName}".</message>
+  <message key="org.apache.fop.fo.FOValidationEventProducer.altTextMissing">Alternate text is missing on {foElement}.{{locator}}</message>
 </catalogue>
Index: src/java/org/apache/fop/fo/FONode.java
===================================================================
--- src/java/org/apache/fop/fo/FONode.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/fo/FONode.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -36,6 +36,7 @@
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fo.extensions.ExtensionAttachment;
 import org.apache.fop.fo.extensions.ExtensionElementMapping;
+import org.apache.fop.fo.extensions.InternalElementMapping;
 import org.apache.fop.fo.extensions.svg.SVGElementMapping;
 import org.apache.fop.fo.pagination.Root;
 import org.apache.fop.util.CharUtilities;
@@ -415,6 +416,8 @@
             return "fo:" + localName;
         } else if (namespaceURI.equals(ExtensionElementMapping.URI)) {
             return "fox:" + localName;
+        } else if (namespaceURI.equals(InternalElementMapping.URI)) {
+            return "foi:" + localName;  // used FOP internally for accessibility
         } else if (namespaceURI.equals(SVGElementMapping.URI)) {
             return "svg:" + localName;
         } else {
Index: src/java/org/apache/fop/fo/Constants.java
===================================================================
--- src/java/org/apache/fop/fo/Constants.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/fo/Constants.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -771,8 +771,16 @@
      * multi-column layouts.
      */
     int PR_X_DISABLE_COLUMN_BALANCING = 273;
+    /** Property constant - FOP proprietary: FOP internal use for accessibility */
+    int PR_X_PTR = 274;
+    /**
+     * Property constant - FOP proprietary: alternative text for e-g and i-f-o.
+     * Used for accessibility.
+     */
+    int PR_X_ALT_TEXT = 275;
+
     /** Number of property constants defined */
-    int PROPERTY_COUNT = 273;
+    int PROPERTY_COUNT = 275;
 
     // compound property constants
 
Index: src/java/org/apache/fop/fo/extensions/ExternalDocument.java
===================================================================
--- src/java/org/apache/fop/fo/extensions/ExternalDocument.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/fo/extensions/ExternalDocument.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -31,7 +31,7 @@
 import org.apache.fop.fo.properties.LengthRangeProperty;
 
 /**
- * Class for the fox:external-document extenstion element.
+ * Class for the fox:external-document extension element.
  */
 public class ExternalDocument extends AbstractPageSequence implements GraphicsProperties {
 
Index: src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java
===================================================================
--- src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -46,6 +46,8 @@
         propertyAttributes.add("orphan-content-limit");
         propertyAttributes.add("internal-destination");
         propertyAttributes.add("disable-column-balancing");
+        //These are FOP's extension properties for accessibility
+        propertyAttributes.add("alt-text");
     }
 
     /**
Index: src/java/org/apache/fop/fo/extensions/InternalElementMapping.java
===================================================================
--- src/java/org/apache/fop/fo/extensions/InternalElementMapping.java (.../trunk) (revision 0)
+++ src/java/org/apache/fop/fo/extensions/InternalElementMapping.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,73 @@
+/*
+ * 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.extensions;
+
+import java.util.HashMap;
+import java.util.Set;
+
+import org.apache.xmlgraphics.util.QName;
+
+import org.apache.fop.fo.ElementMapping;
+
+/**
+ * Element mapping for FOP's internal extension to XSL-FO.
+ */
+public class InternalElementMapping extends ElementMapping {
+
+    /** The FOP extension namespace URI */
+    public static final String URI = "http://xmlgraphics.apache.org/fop/internal";
+
+    private static final Set PROPERTY_ATTRIBUTES = new java.util.HashSet();
+
+    static {
+        //These are FOP's extension properties for accessibility
+        PROPERTY_ATTRIBUTES.add("ptr");
+    }
+
+    /**
+     * Constructor.
+     */
+    public InternalElementMapping() {
+        namespaceURI = URI;
+    }
+
+    /**
+     * Initialize the data structures.
+     */
+    protected void initialize() {
+        if (foObjs == null) {
+            foObjs = new HashMap();
+        }
+    }
+
+    /** {@inheritDoc} */
+    public String getStandardPrefix() {
+        return "foi";
+    }
+
+    /** {@inheritDoc} */
+    public boolean isAttributeProperty(QName attributeName) {
+        if (!URI.equals(attributeName.getNamespaceURI())) {
+            throw new IllegalArgumentException("The namespace URIs don't match");
+        }
+        return PROPERTY_ATTRIBUTES.contains(attributeName.getLocalName());
+    }
+
+}

Property changes on: src/java/org/apache/fop/fo/extensions/InternalElementMapping.java
___________________________________________________________________
Added: svn:eol-style
   + native
Added: svn:keywords
   + Id

Index: src/java/org/apache/fop/fo/flow/BasicLink.java
===================================================================
--- src/java/org/apache/fop/fo/flow/BasicLink.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/fo/flow/BasicLink.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -65,6 +65,7 @@
     /** {@inheritDoc} */
     public void bind(PropertyList pList) throws FOPException {
         super.bind(pList);
+
         // destinationPlacementOffset = pList.get(PR_DESTINATION_PLACEMENT_OFFSET);
         externalDestination = pList.get(PR_EXTERNAL_DESTINATION).getString();
         // indicateDestination = pList.get(PR_INDICATE_DESTINATION);
Index: src/java/org/apache/fop/fo/flow/AbstractPageNumberCitation.java
===================================================================
--- src/java/org/apache/fop/fo/flow/AbstractPageNumberCitation.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/fo/flow/AbstractPageNumberCitation.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -21,8 +21,8 @@
 
 import java.awt.Color;
 
+import org.xml.sax.Attributes;
 import org.xml.sax.Locator;
-import org.xml.sax.Attributes;
 
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.datatypes.Length;
@@ -35,6 +35,7 @@
 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;
 
 /**
  * Common base class for the <a href="http://www.w3.org/TR/xsl/#fo_page-number-citation">
@@ -42,7 +43,8 @@
  * <a href="http://www.w3.org/TR/xsl/#fo_page-number-citation-last">
  * <code>fo:page-number-citation-last</code></a> objects.
  */
-public abstract class AbstractPageNumberCitation extends FObj {
+public abstract class AbstractPageNumberCitation extends FObj
+            implements StructurePointerPropertySet {
 
     // The value of properties relevant for fo:page-number-citation(-last).
     private CommonBorderPaddingBackground commonBorderPaddingBackground;
@@ -51,6 +53,7 @@
     private int alignmentBaseline;
     private Length baselineShift;
     private int dominantBaseline;
+    private String ptr;  // used for accessibility
     // private ToBeImplementedProperty letterSpacing;
     private SpaceProperty lineHeight;
     private String refId;
@@ -96,6 +99,7 @@
         dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum();
         // letterSpacing = pList.get(PR_LETTER_SPACING);
         lineHeight = pList.get(PR_LINE_HEIGHT).getSpace();
+        ptr = pList.get(PR_X_PTR).getString();   // used for accessibility
         refId = pList.get(PR_REF_ID).getString();
         textDecoration = pList.getTextDecorationProps();
         // textShadow = pList.get(PR_TEXT_SHADOW);
@@ -138,6 +142,11 @@
         return textDecoration;
     }
 
+    /** {@inheritDoc} */
+    public String getPtr() {
+        return ptr;
+    }
+
     /** @return the "alignment-adjust" property */
     public Length getAlignmentAdjust() {
         return alignmentAdjust;
Index: src/java/org/apache/fop/fo/flow/AbstractGraphics.java
===================================================================
--- src/java/org/apache/fop/fo/flow/AbstractGraphics.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/fo/flow/AbstractGraphics.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -29,6 +29,7 @@
 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;
 
 /**
  * Common base class for the <a href="http://www.w3.org/TR/xsl/#fo_instream-foreign-object">
@@ -36,7 +37,8 @@
  * and <a href="http://www.w3.org/TR/xsl/#fo_external-graphic">
  * <code>fo:external-graphic</code></a> flow formatting objects.
  */
-public abstract class AbstractGraphics extends FObj implements GraphicsProperties {
+public abstract class AbstractGraphics extends FObj
+        implements GraphicsProperties, StructurePointerPropertySet {
 
     // The value of properties relevant for fo:instream-foreign-object
     // and external-graphics.
@@ -60,6 +62,7 @@
     private int scaling;
     private int textAlign;
     private Length width;
+    private String ptr;   // used for accessibility
     // Unused but valid items, commented out for performance:
     //     private CommonAccessibility commonAccessibility;
     //     private CommonAural commonAural;
@@ -94,6 +97,7 @@
         dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum();
         height = pList.get(PR_HEIGHT).getLength();
         id = pList.get(PR_ID).getString();
+        ptr = pList.get(PR_X_PTR).getString();   // used for accessibility
         inlineProgressionDimension = pList.get(PR_INLINE_PROGRESSION_DIMENSION).getLengthRange();
         keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep();
         keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep();
@@ -102,6 +106,12 @@
         scaling = pList.get(PR_SCALING).getEnum();
         textAlign = pList.get(PR_TEXT_ALIGN).getEnum();
         width = pList.get(PR_WIDTH).getLength();
+        if (getUserAgent().isAccessibilityEnabled()) {
+            String altText = pList.get(PR_X_ALT_TEXT).getString();
+            if (altText.equals("")) {
+                getFOValidationEventProducer().altTextMissing(this, getLocalName(), getLocator());
+            }
+        }
     }
 
     /**
@@ -207,6 +217,11 @@
         return keepWithPrevious;
     }
 
+    /** {@inheritDoc} */
+    public String getPtr() {
+        return ptr;
+    }
+
     /** @return the graphic's intrinsic width in millipoints */
     public abstract int getIntrinsicWidth();
 
Index: src/java/org/apache/fop/fo/flow/PageNumber.java
===================================================================
--- src/java/org/apache/fop/fo/flow/PageNumber.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/fo/flow/PageNumber.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -34,12 +34,13 @@
 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;
 
 /**
  * Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_page-number">
  * <code>fo:page-number</code></a> object.
  */
-public class PageNumber extends FObj {
+public class PageNumber extends FObj implements StructurePointerPropertySet {
     // The value of properties relevant for fo:page-number.
     private CommonBorderPaddingBackground commonBorderPaddingBackground;
     private CommonFont commonFont;
@@ -47,6 +48,7 @@
     private int alignmentBaseline;
     private Length baselineShift;
     private int dominantBaseline;
+    private String ptr; // used for accessibility
     // private ToBeImplementedProperty letterSpacing;
     private SpaceProperty lineHeight;
     /** Holds the text decoration values. May be null */
@@ -92,6 +94,7 @@
         // letterSpacing = pList.get(PR_LETTER_SPACING);
         lineHeight = pList.get(PR_LINE_HEIGHT).getSpace();
         textDecoration = pList.getTextDecorationProps();
+        ptr = pList.get(PR_X_PTR).getString(); // used for accessibility
         // textShadow = pList.get(PR_TEXT_SHADOW);
 
         // implicit properties
@@ -166,6 +169,11 @@
     }
 
     /** {@inheritDoc} */
+    public String getPtr() {
+        return ptr;
+    }
+
+    /** {@inheritDoc} */
     public String getLocalName() {
         return "page-number";
     }
Index: src/java/org/apache/fop/fo/flow/table/TableFObj.java
===================================================================
--- src/java/org/apache/fop/fo/flow/table/TableFObj.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/fo/flow/table/TableFObj.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -19,6 +19,9 @@
 
 package org.apache.fop.fo.flow.table;
 
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.datatypes.Numeric;
 import org.apache.fop.datatypes.ValidationPercentBaseContext;
@@ -33,19 +36,19 @@
 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;
-import org.xml.sax.Locator;
-import org.xml.sax.Attributes;
 
 /**
  * Common base class for table-related FOs
  */
-public abstract class TableFObj extends FObj {
+public abstract class TableFObj extends FObj implements StructurePointerPropertySet {
 
     private Numeric borderAfterPrecedence;
     private Numeric borderBeforePrecedence;
     private Numeric borderEndPrecedence;
     private Numeric borderStartPrecedence;
+    private String ptr;
 
     ConditionalBorder borderBefore;
     ConditionalBorder borderAfter;
@@ -71,6 +74,7 @@
         borderBeforePrecedence = pList.get(PR_BORDER_BEFORE_PRECEDENCE).getNumeric();
         borderEndPrecedence = pList.get(PR_BORDER_END_PRECEDENCE).getNumeric();
         borderStartPrecedence = pList.get(PR_BORDER_START_PRECEDENCE).getNumeric();
+        ptr = pList.get(PR_X_PTR).getString();
         if (getNameId() != FO_TABLE //Separate check for fo:table in Table.java
                 && getNameId() != FO_TABLE_CELL
                 && getCommonBorderPaddingBackground().hasPadding(
@@ -235,6 +239,11 @@
         }
     }
 
+    /** {@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.
Index: src/java/org/apache/fop/fo/flow/Inline.java
===================================================================
--- src/java/org/apache/fop/fo/flow/Inline.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/fo/flow/Inline.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -26,17 +26,19 @@
 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 <a href="http://www.w3.org/TR/xsl/#fo_inline">
  * <code>fo:inline</code></a> formatting object.
  */
-public class Inline extends InlineLevel {
+public class Inline extends InlineLevel implements StructurePointerPropertySet {
     // 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;
@@ -66,6 +68,7 @@
         alignmentBaseline = pList.get(PR_ALIGNMENT_BASELINE).getEnum();
         baselineShift = pList.get(PR_BASELINE_SHIFT).getLength();
         dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum();
+        ptr = pList.get(PR_X_PTR).getString(); // used for accessibility
     }
 
     /** {@inheritDoc} */
@@ -145,6 +148,11 @@
     }
 
     /** {@inheritDoc} */
+    public String getPtr() {
+        return ptr;
+    }
+
+    /** {@inheritDoc} */
     public String getLocalName() {
         return "inline";
     }
Index: src/java/org/apache/fop/fo/flow/Block.java
===================================================================
--- src/java/org/apache/fop/fo/flow/Block.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/fo/flow/Block.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -21,6 +21,8 @@
 
 import java.awt.Color;
 
+import org.xml.sax.Locator;
+
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.datatypes.Length;
 import org.apache.fop.datatypes.Numeric;
@@ -38,13 +40,13 @@
 import org.apache.fop.fo.properties.CommonRelativePosition;
 import org.apache.fop.fo.properties.KeepProperty;
 import org.apache.fop.fo.properties.SpaceProperty;
-import org.xml.sax.Locator;
+import org.apache.fop.fo.properties.StructurePointerPropertySet;
 
  /**
   * Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_block">
   * <code>fo:block object</code></a>.
   */
-public class Block extends FObjMixed implements BreakPropertySet {
+public class Block extends FObjMixed implements BreakPropertySet, StructurePointerPropertySet {
 
     // used for FO validation
     private boolean blockOrInlineItemFound = false;
@@ -71,6 +73,7 @@
     private int lineHeightShiftAdjustment;
     private int lineStackingStrategy;
     private Numeric orphans;
+    private String ptr;  //used for accessibility
     private int whiteSpaceTreatment;
     private int span;
     private int textAlign;
@@ -122,6 +125,7 @@
         lineHeightShiftAdjustment = pList.get(PR_LINE_HEIGHT_SHIFT_ADJUSTMENT).getEnum();
         lineStackingStrategy = pList.get(PR_LINE_STACKING_STRATEGY).getEnum();
         orphans = pList.get(PR_ORPHANS).getNumeric();
+        ptr = pList.get(PR_X_PTR).getString();  //used for accessibility
         whiteSpaceTreatment = pList.get(PR_WHITE_SPACE_TREATMENT).getEnum();
         span = pList.get(PR_SPAN).getEnum();
         textAlign = pList.get(PR_TEXT_ALIGN).getEnum();
@@ -171,6 +175,11 @@
         return breakAfter;
     }
 
+    /** {@inheritDoc} */
+    public String getPtr() {
+        return ptr;
+    }
+
     /** @return the "break-before" property. */
     public int getBreakBefore() {
         return breakBefore;
Index: src/java/org/apache/fop/fo/flow/Character.java
===================================================================
--- src/java/org/apache/fop/fo/flow/Character.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/fo/flow/Character.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -38,12 +38,13 @@
 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;
 
 /**
  * Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_character">
  * <code>fo:character</code></a> object.
  */
-public class Character extends FObj {
+public class Character extends FObj implements StructurePointerPropertySet {
     // The value of properties relevant for fo:character.
     private CommonBorderPaddingBackground commonBorderPaddingBackground;
     private CommonFont commonFont;
@@ -62,6 +63,7 @@
     private CommonTextDecoration textDecoration;
     // private ToBeImplementedProperty textShadow;
     private Property wordSpacing;
+    private String ptr;  // used for accessibility
     // Unused but valid items, commented out for performance:
     //     private CommonAural commonAural;
     //     private CommonMarginInline commonMarginInline;
@@ -108,6 +110,7 @@
         lineHeight = pList.get(PR_LINE_HEIGHT).getSpace();
         textDecoration = pList.getTextDecorationProps();
         wordSpacing = pList.get(PR_WORD_SPACING);
+        ptr = pList.get(PR_X_PTR).getString();  // used for accessibility
     }
 
     /** {@inheritDoc} */
@@ -208,6 +211,11 @@
     }
 
     /** {@inheritDoc} */
+    public String getPtr() {
+        return ptr;
+    }
+
+    /** {@inheritDoc} */
     public String getLocalName() {
         return "character";
     }
Index: src/java/org/apache/fop/fo/properties/StructurePointerPropertySet.java
===================================================================
--- src/java/org/apache/fop/fo/properties/StructurePointerPropertySet.java (.../trunk) (revision 0)
+++ src/java/org/apache/fop/fo/properties/StructurePointerPropertySet.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,34 @@
+/*
+ * 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;
+
+/**
+ * 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();
+
+}

Property changes on: src/java/org/apache/fop/fo/properties/StructurePointerPropertySet.java
___________________________________________________________________
Added: svn:eol-style
   + native
Added: svn:keywords
   + Id

Index: src/java/org/apache/fop/fo/FOValidationEventProducer.java
===================================================================
--- src/java/org/apache/fop/fo/FOValidationEventProducer.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/fo/FOValidationEventProducer.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -36,8 +36,10 @@
     /**
      * Provider class for the event producer.
      */
-    class Provider {
+    final class Provider {
 
+        private Provider() { }
+
         /**
          * Returns an event producer.
          * @param broadcaster the event broadcaster to use
@@ -354,4 +356,13 @@
     void unknownFormattingObject(Object source, String elementName,
             QName offendingNode, Locator loc);
 
+    /**
+     * Alternate text is missing for a graphic element.
+     *
+     * @param source the event source
+     * @param foElement name of the element (external-graphic or instream-foreign-object)
+     * @param loc the location of the error or null
+     * @event.severity WARN
+     */
+    void altTextMissing(Object source, String foElement, Locator loc);
 }
Index: src/java/org/apache/fop/fo/FOPropertyMapping.java
===================================================================
--- src/java/org/apache/fop/fo/FOPropertyMapping.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/fo/FOPropertyMapping.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -2515,6 +2515,18 @@
         m.setDefault("");
         addPropertyMaker("id", m);
 
+        // foi:ptr, used for accessibility
+        m = new StringProperty.Maker(PR_X_PTR);
+        m.setInherited(false);
+        m.setDefault("");
+        addPropertyMaker("foi:ptr", m);
+
+        // fox:alt-text, used for accessibility
+        m = new StringProperty.Maker(PR_X_ALT_TEXT);
+        m.setInherited(false);
+        m.setDefault("");
+        addPropertyMaker("fox:alt-text", m);
+
         // provisional-label-separation
         m  = new LengthProperty.Maker(PR_PROVISIONAL_LABEL_SEPARATION);
         m.setInherited(true);
Index: src/java/org/apache/fop/cli/CommandLineOptions.java
===================================================================
--- src/java/org/apache/fop/cli/CommandLineOptions.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/cli/CommandLineOptions.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -36,6 +36,7 @@
 import org.apache.commons.logging.LogFactory;
 
 import org.apache.fop.Version;
+import org.apache.fop.accessibility.Accessibility;
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.FopFactory;
@@ -340,6 +341,8 @@
                 i = i + parseAreaTreeOption(args, i);
             } else if (args[i].equals("-if")) {
                 i = i + parseIntermediateFormatOption(args, i);
+            } else if (args[i].equals("-a")) {
+                this.renderingOptions.put(Accessibility.ACCESSIBILITY, Boolean.TRUE);
             } else if (args[i].equals("-v")) {
                 /* Currently just print the version */
                 printVersion();
@@ -1147,6 +1150,7 @@
             + "  -nocopy           PDF file will be encrypted without copy content permission\n"
             + "  -noedit           PDF file will be encrypted without edit content permission\n"
             + "  -noannotations    PDF file will be encrypted without edit annotation permission\n"
+            + "  -a                enables accessibility features (Tagged PDF etc., default off)\n"
             + "  -pdfprofile prof  PDF file will be generated with the specified profile\n"
             + "                    (Examples for prof: PDF/A-1b or PDF/X-3:2003)\n\n"
             + "  -conserve         Enable memory-conservation policy (trades memory-consumption for disk I/O)\n"
Index: src/java/org/apache/fop/area/AreaTreeParser.java
===================================================================
--- src/java/org/apache/fop/area/AreaTreeParser.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/area/AreaTreeParser.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -39,8 +39,6 @@
 import javax.xml.transform.sax.SAXTransformerFactory;
 import javax.xml.transform.sax.TransformerHandler;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.w3c.dom.DOMImplementation;
 import org.w3c.dom.Document;
 import org.xml.sax.Attributes;
@@ -50,12 +48,17 @@
 import org.xml.sax.helpers.AttributesImpl;
 import org.xml.sax.helpers.DefaultHandler;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
 import org.apache.xmlgraphics.image.loader.ImageException;
 import org.apache.xmlgraphics.image.loader.ImageInfo;
 import org.apache.xmlgraphics.image.loader.ImageManager;
 import org.apache.xmlgraphics.image.loader.ImageSessionContext;
 import org.apache.xmlgraphics.util.QName;
 
+import org.apache.fop.accessibility.AccessibilityEventProducer;
+import org.apache.fop.accessibility.StructureTreeBuilder;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.area.Trait.Background;
 import org.apache.fop.area.Trait.InternalLink;
@@ -84,6 +87,8 @@
 import org.apache.fop.util.ContentHandlerFactoryRegistry;
 import org.apache.fop.util.ConversionUtils;
 import org.apache.fop.util.DefaultErrorListener;
+import org.apache.fop.util.DelegatingContentHandler;
+import org.apache.fop.util.XMLConstants;
 import org.apache.fop.util.XMLUtil;
 
 /**
@@ -156,6 +161,26 @@
         private Locator locator;
 
 
+        private StructureTreeBuilder structureTreeBuilder;
+
+        private ContentHandler structureTreeBuilderWrapper;
+
+        private Attributes pageSequenceAttributes;
+
+        private final class StructureTreeBuilderWrapper extends DelegatingContentHandler {
+
+            private StructureTreeBuilderWrapper()
+                    throws SAXException {
+                super(structureTreeBuilder.getHandlerForNextPageSequence());
+            }
+
+            public void endDocument() throws SAXException {
+                super.endDocument();
+                startAreaTreeElement("pageSequence", pageSequenceAttributes);
+                pageSequenceAttributes = null;
+            }
+        }
+
         public Handler(AreaTreeModel treeModel, FOUserAgent userAgent,
                 ElementMappingRegistry elementMappingRegistry) {
             this.treeModel = treeModel;
@@ -192,6 +217,11 @@
             makers.put("bookmarkTree", new BookmarkTreeMaker());
             makers.put("bookmark", new BookmarkMaker());
             makers.put("destination", new DestinationMaker());
+
+            if (userAgent.isAccessibilityEnabled()) {
+                structureTreeBuilder = new StructureTreeBuilder(tFactory);
+                userAgent.setStructureTree(structureTreeBuilder.getStructureTree());
+            }
         }
 
         private Area findAreaType(Class clazz) {
@@ -265,19 +295,35 @@
                 delegate.startDocument();
                 delegate.startElement(uri, localName, qName, attributes);
             } else {
-                lastAttributes = new AttributesImpl(attributes);
                 boolean handled = true;
                 if ("".equals(uri)) {
-                    Maker maker = (Maker)makers.get(localName);
-                    content.clear();
-                    ignoreCharacters = true;
-                    if (maker != null) {
-                        ignoreCharacters = maker.ignoreCharacters();
-                        maker.startElement(attributes);
-                    } else if ("extension-attachments".equals(localName)) {
-                        //TODO implement me
+                    if (localName.equals("pageSequence") && userAgent.isAccessibilityEnabled()) {
+                        structureTreeBuilderWrapper = new StructureTreeBuilderWrapper();
+                        pageSequenceAttributes = new AttributesImpl(attributes);
+                    } else if (localName.equals("structureTree")) {
+                        if (userAgent.isAccessibilityEnabled()) {
+                            delegate = structureTreeBuilderWrapper;
+                        } else {
+                            /* Delegate to a handler that does nothing */
+                            delegate = new DefaultHandler();
+                        }
+                        delegateStack.push(qName);
+                        delegate.startDocument();
+                        delegate.startElement(uri, localName, qName, attributes);
                     } else {
-                        handled = false;
+                        if (pageSequenceAttributes != null) {
+                            /*
+                             * This means that no structure-element tag was
+                             * found in the XML, otherwise a
+                             * StructureTreeBuilderWrapper object would have
+                             * been created, which would have reset the
+                             * pageSequenceAttributes field.
+                             */
+                            AccessibilityEventProducer.Provider
+                                    .get(userAgent.getEventBroadcaster())
+                                    .noStructureTreeInXML(this);
+                        }
+                        handled = startAreaTreeElement(localName, attributes);
                     }
                 } else {
                     ContentHandlerFactoryRegistry registry
@@ -304,6 +350,23 @@
             }
         }
 
+        private boolean startAreaTreeElement(String localName, Attributes attributes)
+                throws SAXException {
+            lastAttributes = new AttributesImpl(attributes);
+            Maker maker = (Maker)makers.get(localName);
+            content.clear();
+            ignoreCharacters = true;
+            if (maker != null) {
+                ignoreCharacters = maker.ignoreCharacters();
+                maker.startElement(attributes);
+            } else if ("extension-attachments".equals(localName)) {
+                //TODO implement me
+            } else {
+                return false;
+            }
+            return true;
+        }
+
         /** {@inheritDoc} */
         public void endElement(String uri, String localName, String qName) throws SAXException {
             if (delegate != null) {
@@ -700,6 +763,7 @@
                 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);
@@ -748,6 +812,7 @@
                         "tlsadjust", 0));
                 text.setTextWordSpaceAdjust(XMLUtil.getAttributeAsInt(attributes,
                         "twsadjust", 0));
+                setPtr(text, attributes);
                 Area parent = (Area)areaStack.peek();
                 parent.addChildArea(text);
                 areaStack.push(text);
@@ -840,6 +905,7 @@
                 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);
@@ -858,6 +924,7 @@
                 transferForeignObjects(attributes, image);
                 setAreaAttributes(attributes, image);
                 setTraits(attributes, image, SUBSET_COMMON);
+                setPtr(image, attributes);
                 getCurrentViewport().setContent(image);
             }
         }
@@ -991,10 +1058,10 @@
                     ExtensionAttachment attachment = (ExtensionAttachment)obj;
                     ato.addExtensionAttachment(attachment);
                 } else {
-                    log.warn("Don't know how to handle externally generated object: " + obj);
-                }
+                log.warn("Don't know how to handle externally generated object: " + obj);
             }
         }
+        }
 
         private void setAreaAttributes(Attributes attributes, Area area) {
             area.setIPD(Integer.parseInt(attributes.getValue("ipd")));
@@ -1133,7 +1200,7 @@
             for (int i = 0, c = atts.getLength(); i < c; i++) {
                 String ns = atts.getURI(i);
                 if (ns.length() > 0) {
-                    if ("http://www.w3.org/2000/xmlns/".equals(ns)) {
+                    if (XMLConstants.XMLNS_NAMESPACE_URI.equals(ns)) {
                         continue;
                     }
                     QName qname = new QName(ns, atts.getQName(i));
@@ -1142,6 +1209,13 @@
             }
         }
 
+        private void setPtr(Area area, Attributes attributes) {
+            String ptr = attributes.getValue("ptr");
+            if (ptr != null) {
+                area.addTrait(Trait.PTR, ptr);
+            }
+        }
+
         /** {@inheritDoc} */
         public void characters(char[] ch, int start, int length) throws SAXException {
             if (delegate != null) {
Index: src/java/org/apache/fop/area/Trait.java
===================================================================
--- src/java/org/apache/fop/area/Trait.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/area/Trait.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -194,9 +194,12 @@
     public static final Integer OVERLINE_COLOR = new Integer(35);
     /** Trait for color of linethrough decorations when rendering inline parent. */
     public static final Integer LINETHROUGH_COLOR = new Integer(36);
+    
+    /** The ptr trait. Used for accessibility   */
+    public static final Integer PTR = new Integer(37);
 
     /** Maximum value used by trait keys */
-    public static final int MAX_TRAIT_KEY = 36;
+    public static final int MAX_TRAIT_KEY = 37;
 
     private static final TraitInfo[] TRAIT_INFO = new TraitInfo[MAX_TRAIT_KEY + 1];
 
@@ -225,6 +228,7 @@
     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(INTERNAL_LINK, new TraitInfo("internal-link", InternalLink.class));
         put(EXTERNAL_LINK, new TraitInfo("external-link", ExternalLink.class));
         put(FONT,         new TraitInfo("font", FontTriplet.class));
Index: src/java/org/apache/fop/pdf/PDFAMode.java
===================================================================
--- src/java/org/apache/fop/pdf/PDFAMode.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/pdf/PDFAMode.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -44,7 +44,18 @@
         return this.name;
     }
 
-    /** @return true if this mode obey the restrictions established by PDF/A-1b. */
+    /**
+     * Indicates whether this mode obeys the restrictions established by PDF/A-1a.
+     * @return true if this mode obeys the restrictions established by PDF/A-1a.
+     */
+    public boolean isPDFA1LevelA() {
+        return (this != DISABLED);
+    }
+
+    /**
+     * Indicates whether this mode obeys the restrictions established by PDF/A-1b.
+     * @return true if this mode obeys the restrictions established by PDF/A-1b.
+     */
     public boolean isPDFA1LevelB() {
         return (this != DISABLED);
         //PDF/A-1a is a superset of PDF/A-1b!
Index: src/java/org/apache/fop/pdf/PDFProfile.java
===================================================================
--- src/java/org/apache/fop/pdf/PDFProfile.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/pdf/PDFProfile.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -58,9 +58,6 @@
      */
     protected void validateProfileCombination() {
         if (pdfAMode != PDFAMode.DISABLED) {
-            if (pdfAMode == PDFAMode.PDFA_1A) {
-                throw new UnsupportedOperationException("PDF/A-1a is not implemented, yet");
-            }
             if (pdfAMode == PDFAMode.PDFA_1B) {
                 if (pdfXMode != PDFXMode.DISABLED && pdfXMode != PDFXMode.PDFX_3_2003) {
                     throw new PDFConformanceException(
@@ -192,6 +189,32 @@
         }
     }
 
+    /**
+     * Checks a few things required for tagged PDF.
+     */
+    public void verifyTaggedPDF() {
+        if (getPDFAMode().isPDFA1LevelA()) {
+            final String err = "{0} requires the {1} dictionary entry to be set";
+            PDFDictionary markInfo = getDocument().getRoot().getMarkInfo();
+            if (markInfo == null) {
+                throw new PDFConformanceException(format(
+                        "{0} requires the MarkInfo dictionary to be present", getPDFAMode()));
+            }
+            if (!Boolean.TRUE.equals(markInfo.get("Marked"))) {
+                throw new PDFConformanceException(format(err,
+                        new Object[] {getPDFAMode(), "Marked"}));
+            }
+            if (getDocument().getRoot().getStructTreeRoot() == null) {
+                throw new PDFConformanceException(format(err,
+                        new Object[] {getPDFAMode(), "StructTreeRoot"}));
+            }
+            if (getDocument().getRoot().getLanguage() == null) {
+                throw new PDFConformanceException(format(err,
+                        new Object[] {getPDFAMode(), "Lang"}));
+            }
+        }
+    }
+
     /** @return true if the ID entry must be present in the trailer. */
     public boolean isIDEntryRequired() {
         return isPDFAActive() || isPDFXActive();
Index: src/java/org/apache/fop/pdf/PDFArray.java
===================================================================
--- src/java/org/apache/fop/pdf/PDFArray.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/pdf/PDFArray.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -107,6 +107,15 @@
     }
 
     /**
+     * Indicates whether the given object exists in the array.
+     * @param obj the object to look for
+     * @return true if obj is contained
+     */
+    public boolean contains(Object obj) {
+        return this.values.contains(obj);
+    }
+
+    /**
      * Returns the length of the array
      * @return the length of the array
      */
Index: src/java/org/apache/fop/pdf/PDFNumsArray.java
===================================================================
--- src/java/org/apache/fop/pdf/PDFNumsArray.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/pdf/PDFNumsArray.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -57,8 +57,17 @@
      * @param key the key of the value to set
      * @param obj the new value
      */
+    public void put(Integer key, Object obj) {
+        this.map.put(key, obj);
+    }
+
+    /**
+     * Sets an entry.
+     * @param key the key of the value to set
+     * @param obj the new value
+     */
     public void put(int key, Object obj) {
-        this.map.put(new Integer(key), obj);
+        put(new Integer(key), obj);
     }
 
     /**
@@ -66,8 +75,17 @@
      * @param key the key of requested value
      * @return the requested value
      */
+    public Object get(Integer key) {
+        return this.map.get(key);
+    }
+
+    /**
+     * Gets an entry.
+     * @param key the key of requested value
+     * @return the requested value
+     */
     public Object get(int key) {
-        return this.map.get(new Integer(key));
+        return get(new Integer(key));
     }
 
     /** {@inheritDoc} */
Index: src/java/org/apache/fop/pdf/PDFRoot.java
===================================================================
--- src/java/org/apache/fop/pdf/PDFRoot.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/pdf/PDFRoot.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -19,6 +19,9 @@
 
 package org.apache.fop.pdf;
 
+import java.io.IOException;
+import java.io.OutputStream;
+
 /**
  * Class representing a Root (/Catalog) object.
  */
@@ -56,7 +59,7 @@
      * object must be created before the PDF document is
      * generated, but it is not assigned an object ID until
      * it is about to be written (immediately before the xref
-     * table as part of the trsailer). (mark-fop@...)
+     * table as part of the trailer). (mark-fop@...)
      *
      * @param objnum the object's number
      * @param pages the PDFPages object
@@ -68,6 +71,12 @@
         setRootPages(pages);
     }
 
+    /** {@inheritDoc} */
+    protected int output(OutputStream stream) throws IOException {
+        getDocument().getProfile().verifyTaggedPDF();
+        return super.output(stream);
+    }
+
     /**
      * Set the page mode for the PDF document.
      *
@@ -252,4 +261,39 @@
         put("Lang", lang);
     }
 
+    /**
+     * Sets the StructTreeRoot object. Used for accessibility.
+     * @param structTreeRoot of this document
+     */
+    public void setStructTreeRoot(PDFStructTreeRoot structTreeRoot) {
+        if (structTreeRoot == null) {
+            throw new NullPointerException("structTreeRoot must not be null");
+        }
+        put("StructTreeRoot", structTreeRoot);
+    }
+
+    /**
+     * Returns the StructTreeRoot object.
+     * @return the structure tree root (or null if accessibility is not enabled)
+     */
+    public PDFStructTreeRoot getStructTreeRoot() {
+        return (PDFStructTreeRoot)get("StructTreeRoot");
+    }
+
+    /**
+     * Marks this document as conforming to the Tagged PDF conventions.
+     */
+    public void makeTagged() {
+        PDFDictionary dict = new PDFDictionary();
+        dict.put("Marked", Boolean.TRUE);
+        put("MarkInfo", dict);  //new PDFMarkInfo()
+    }
+
+    /**
+     * Returns the MarkInfo dictionary.
+     * @return the MarkInfo dictionary (or null if it's not present)
+     */
+    public PDFDictionary getMarkInfo() {
+        return (PDFDictionary)get("MarkInfo");
+    }
 }
Index: src/java/org/apache/fop/pdf/PDFStructTreeRoot.java
===================================================================
--- src/java/org/apache/fop/pdf/PDFStructTreeRoot.java (.../trunk) (revision 0)
+++ src/java/org/apache/fop/pdf/PDFStructTreeRoot.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,55 @@
+/*
+ * 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.pdf;
+
+/**
+ * Class representing a PDF /StructTreeRoot dictionary.
+ */
+public class PDFStructTreeRoot extends PDFDictionary {
+
+    /**
+     * Creates a new /StructTreeRoot dictionary.
+     *
+     * @param parentTree the value of the ParenTree entry
+     */
+    PDFStructTreeRoot(PDFParentTree parentTree) {
+        put("Type", new PDFName("StructTreeRoot"));
+        put("K", new PDFArray());
+        put("ParentTree", parentTree);
+    }
+
+    /**
+     * Returns the children element of this StructTreeRoot.
+     *
+     * @return the value of the K entry
+     */
+    public PDFArray getKids() {
+        return (PDFArray)get("K");
+    }
+
+    /**
+     * Adds the given object to the array of kids.
+     *
+     * @param kid an object to be added to the K entry
+     */
+    public void addKid(PDFObject kid) {
+        getKids().add(kid);
+    }
+}
\ No newline at end of file

Property changes on: src/java/org/apache/fop/pdf/PDFStructTreeRoot.java
___________________________________________________________________
Added: svn:eol-style
   + native
Added: svn:keywords
   + Id

Index: src/java/org/apache/fop/pdf/PDFParentTree.java
===================================================================
--- src/java/org/apache/fop/pdf/PDFParentTree.java (.../trunk) (revision 0)
+++ src/java/org/apache/fop/pdf/PDFParentTree.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,44 @@
+/*
+ * 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.pdf;
+
+/**
+ * Class representing a PDF /ParentTree.
+ */
+public class PDFParentTree extends PDFNumberTreeNode {
+
+    /**
+     * Returns the number tree corresponding to this parent tree.
+     *
+     * @return the number tree
+     */
+    public PDFNumsArray getNums() {
+        PDFNumsArray nums = super.getNums();
+        if (nums == null) {
+            nums = new PDFNumsArray(this);
+            setNums(nums);
+        }
+        return nums;
+    }
+}
+
+
+
+

Property changes on: src/java/org/apache/fop/pdf/PDFParentTree.java
___________________________________________________________________
Added: svn:eol-style
   + native
Added: svn:keywords
   + Id

Index: src/java/org/apache/fop/pdf/PDFDocument.java
===================================================================
--- src/java/org/apache/fop/pdf/PDFDocument.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/pdf/PDFDocument.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -355,6 +355,25 @@
     }
 
     /**
+     * Makes sure a Lang entry has been set on the document catalog, setting it
+     * to a default value if necessary. When accessibility is enabled the
+     * language must be specified for any text element in the document.
+     */
+    public void enforceLanguageOnRoot() {
+        if (root.getLanguage() == null) {
+            String fallbackLanguage;
+            if (getProfile().getPDFAMode().isPDFA1LevelA()) {
+                //According to Annex B of ISO-19005-1:2005(E), section B.2
+                fallbackLanguage = "x-unknown";
+            } else {
+                //No language has been set on the first page-sequence, so fall back to "en".
+                fallbackLanguage = "en";
+            }
+            root.setLanguage(fallbackLanguage);
+        }
+    }
+
+    /**
      * Get the {@link PDFInfo} object for this document.
      *
      * @return the {@link PDFInfo} object
Index: src/java/org/apache/fop/pdf/PDFFactory.java
===================================================================
--- src/java/org/apache/fop/pdf/PDFFactory.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/pdf/PDFFactory.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -185,6 +185,10 @@
     public PDFPage makePage(PDFResources resources, int pageIndex,
                             Rectangle2D mediaBox, Rectangle2D cropBox,
                             Rectangle2D bleedBox, Rectangle2D trimBox) {
+        /*
+         * create a PDFPage with the next object number, the given
+         * resources, contents and dimensions
+         */
         PDFPage page = new PDFPage(resources, pageIndex, mediaBox, cropBox, bleedBox, trimBox);
 
         getDocument().assignObjectNumber(page);
@@ -883,6 +887,35 @@
     }
 
     /**
+     * Creates and returns a StructTreeRoot object. Used for accessibility.
+     * @param parentTree the value of the ParenTree entry
+     * @return structure Tree Root element
+     */
+    public PDFStructTreeRoot makeStructTreeRoot(PDFParentTree parentTree) {
+        PDFStructTreeRoot structTreeRoot = new PDFStructTreeRoot(parentTree);
+        getDocument().assignObjectNumber(structTreeRoot);
+        getDocument().addTrailerObject(structTreeRoot);
+        getDocument().getRoot().setStructTreeRoot(structTreeRoot);
+        return structTreeRoot;
+    }
+
+    /**
+     * Creates and returns a StructElem object.
+     *
+     * @param structureType the structure type of the new element (value for the
+     * S entry)
+     * @param parent the parent of the new structure element in the structure
+     * hierarchy
+     * @return the newly created element
+     */
+    public PDFStructElem makeStructureElement(PDFName structureType, PDFObject parent) {
+        PDFStructElem structElem = new PDFStructElem(parent, structureType);
+        getDocument().assignObjectNumber(structElem);
+        getDocument().addTrailerObject(structElem);
+        return structElem;
+    }
+
+    /**
      * Make a the head object of the name dictionary (the /Dests object).
      *
      * @param destinationList a list of PDFDestination instances
Index: src/java/org/apache/fop/pdf/PDFPage.java
===================================================================
--- src/java/org/apache/fop/pdf/PDFPage.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/pdf/PDFPage.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -154,4 +154,33 @@
         return this.pageIndex;
     }
 
+    /**
+     * Sets the "StructParents" value.
+     * @param structParents the integer key of this object's entry in the structural parent tree.
+     */
+    public void setStructParents(int structParents) {
+        put("StructParents", structParents);
+        //This is a PDF 1.5 feature. It is set as a work-around for a bug in Adobe Acrobat
+        //which reports this missing even if the PDF file is PDF 1.4.
+        setTabs(new PDFName("S"));
+    }
+
+    /**
+     * Returns the value of the StructParents entry.
+     *
+     * @return the StructParents value, <code>null</code> if the entry has not been set
+     */
+    public Integer getStructParents() {
+        return (Integer) get("StructParents");
+    }
+
+    /**
+     * Specifies the tab order for annotations on a page.
+     * @param value one of the allowed values (see PDF 1.5)
+     * @since PDF 1.5
+     */
+    public void setTabs(PDFName value) {
+        put("Tabs", value);
+    }
+
 }
Index: src/java/org/apache/fop/pdf/PDFStructElem.java
===================================================================
--- src/java/org/apache/fop/pdf/PDFStructElem.java (.../trunk) (revision 0)
+++ src/java/org/apache/fop/pdf/PDFStructElem.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,159 @@
+/*
+ * 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.pdf;
+
+import java.util.Locale;
+
+import org.apache.fop.util.XMLUtil;
+
+/**
+ * Class representing a PDF Structure Element.
+ */
+public class PDFStructElem extends PDFDictionary {
+
+    private PDFStructElem parentElement;
+
+    /**
+     * Creates a new structure element.
+     *
+     * @param parent parent of this element
+     * @param structureType the structure type of this element
+     */
+    PDFStructElem(PDFObject parent, PDFName structureType) {
+        if (parent instanceof PDFStructElem) {
+            parentElement = (PDFStructElem) parent;
+        }
+        put("Type", new PDFName("StructElem"));
+        put("S", structureType);
+        setParent(parent);
+    }
+
+    /**
+     * Returns the parent of this structure element.
+     *
+     * @return the parent, <code>null</code> if the parent is not a structure
+     * element (i.e., is the structure tree root)
+     */
+    public PDFStructElem getParentStructElem() {
+        return parentElement;
+    }
+
+    /** {@inheritDoc} */
+    public void setParent(PDFObject parent) {
+        if (parent != null) {
+           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
+     * parent, and so on.
+     *
+     * @param kid element to be added
+     */
+    public void addKid(PDFObject kid) {
+        PDFArray kids = getKids();
+        if (kids == null) {
+            kids = new PDFArray();
+            put("K", kids);
+        }
+        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);
+        }
+    }
+
+    /**
+     * Sets the given mcid as the kid of this structure element. This element
+     * will then add itself to its parent structure element if it has not
+     * already, and so will the parent, and so on.
+     *
+     * @param mcid mcid of the marked-content sequence corresponding to this
+     * structure element's kid
+     */
+    public void setMCIDKid(int mcid) {
+        put("K", mcid);
+        joinHierarchy();
+    }
+
+    /**
+     * Sets the page reference of this structure element.
+     *
+     * @param page value for the Pg entry
+     */
+    public void setPage(PDFPage page) {
+        put("Pg", page);
+    }
+
+    /**
+     * Returns the structure type of this structure element.
+     *
+     * @return the value of the S entry
+     */
+    public PDFName getStructureType() {
+        return (PDFName)get("S");
+    }
+
+    /**
+     * Sets the language of this structure element.
+     * @param language the language (as defined in the section about
+     *                          "Natural Language Specification")
+     */
+    private void setLanguage(String language) {
+        put("Lang", language);
+    }
+
+    /**
+     * Sets the language of this structure element.
+     *
+     * @param language a value for the Lang entry
+     */
+    public void setLanguage(Locale language) {
+        setLanguage(XMLUtil.toRFC3066(language));
+    }
+
+    /**
+     * Returns the language of this structure element.
+     *
+     * @return the value of the Lang entry (<code>null</code> if no language was specified)
+     */
+    public String getLanguage() {
+        return (String)get("Lang");
+    }
+}

Property changes on: src/java/org/apache/fop/pdf/PDFStructElem.java
___________________________________________________________________
Added: svn:eol-style
   + native
Added: svn:keywords
   + Id

Index: src/java/org/apache/fop/pdf/PDFLink.java
===================================================================
--- src/java/org/apache/fop/pdf/PDFLink.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/pdf/PDFLink.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -42,6 +42,7 @@
     private float bry;
     private String color;
     private PDFAction action;
+    private Integer structParent;
 
     /**
      * create objects associated with a link annotation (GoToR)
@@ -68,7 +69,17 @@
         this.action = action;
     }
 
+
     /**
+     * Sets the value of the StructParent entry for this link.
+     *
+     * @param structParent key in the structure parent tree
+     */
+    public void setStructParent(int structParent) {
+        this.structParent = new Integer(structParent);
+    }
+
+    /**
      * {@inheritDoc}
      */
     public String toPDFString() {
@@ -87,6 +98,8 @@
                    + (brx) + " " + (bry) + " ]\n" + "/C [ "
                    + this.color + " ]\n" + "/Border [ 0 0 0 ]\n" + "/A "
                    + this.action.getAction() + "\n" + "/H /I\n"
+                   + (this.structParent != null
+                           ? "/StructParent " + this.structParent.toString() + "\n" : "")
                    + fFlag + "\n>>\nendobj\n";
         return s;
     }
Index: src/java/org/apache/fop/util/DOM2SAX.java
===================================================================
--- src/java/org/apache/fop/util/DOM2SAX.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/util/DOM2SAX.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -26,7 +26,6 @@
 import org.w3c.dom.Document;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
-
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 import org.xml.sax.ext.LexicalHandler;
@@ -79,6 +78,15 @@
     }
 
     /**
+     * Writes the given fragment using the given ContentHandler.
+     * @param node DOM node
+     * @throws SAXException In case of a problem while writing XML
+     */
+    public void writeFragment(Node node) throws SAXException {
+        writeNode(node);
+    }
+
+    /**
      * Begin the scope of namespace prefix. Forward the event to the SAX handler
      * only if the prefix is unknown or it is mapped to a different URI.
      */
Index: src/java/org/apache/fop/util/XMLUtil.java
===================================================================
--- src/java/org/apache/fop/util/XMLUtil.java (.../trunk) (revision 824832)
+++ src/java/org/apache/fop/util/XMLUtil.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -21,6 +21,7 @@
 
 import java.awt.Rectangle;
 import java.awt.geom.Rectangle2D;
+import java.util.Locale;
 
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
@@ -170,4 +171,39 @@
         atts.addAttribute("", localName, localName, XMLUtil.CDATA, value);
     }
 
+    /**
+     * Converts a {@link Locale} instance to an RFC 3066 compliant language identifier.
+     * @param language the language
+     * @return the formatted language identifier
+     */
+    public static String toRFC3066(Locale language) {
+        if (language == null || language.getLanguage().length() == 0) {
+            return null;
+        }
+        StringBuffer sb = new StringBuffer();
+        sb.append(language.getLanguage());
+        if (language.getCountry().length() > 0) {
+            sb.append('-');
+            sb.append(language.getCountry());
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Converts an RFC 3066 compliant language identifier to a {@link Locale} instance.
+     * @param lang the language string
+     * @return the converted locale instance
+     */
+    public static Locale convertRFC3066ToLocale(String lang) {
+        if (lang == null || lang.length() == 0) {
+            return null;
+        }
+        String[] parts = lang.split("-");
+        if (parts.length == 1) {
+            return new Locale(parts[0]);
+        } else {
+            return new Locale(parts[0], parts[1]);
+        }
+    }
+
 }
Index: src/java/org/apache/fop/util/TransformerDefaultHandler.java
===================================================================
--- src/java/org/apache/fop/util/TransformerDefaultHandler.java (.../trunk) (revision 0)
+++ src/java/org/apache/fop/util/TransformerDefaultHandler.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,160 @@
+/*
+ * 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.util;
+
+import javax.xml.transform.sax.TransformerHandler;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.DefaultHandler2;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * A DefaultHandler implementation that delegates all the method calls to a
+ * {@link TransformerHandler} instance.
+ */
+public class TransformerDefaultHandler extends DefaultHandler2 {
+
+    private TransformerHandler transformerHandler;
+
+    /**
+     * Creates a new instance delegating to the given TransformerHandler object.
+     *
+     * @param transformerHandler the object to which all the method calls will
+     * be delegated
+     */
+    public TransformerDefaultHandler(TransformerHandler transformerHandler) {
+        this.transformerHandler = transformerHandler;
+    }
+
+    /**
+     * Returns the delegate TransformerHandler instance.
+     *
+     * @return the object to which all method calls are delegated
+     */
+    public TransformerHandler getTransformerHandler() {
+        return transformerHandler;
+    }
+
+    /** {@inheritDoc} */
+    public void setDocumentLocator(Locator locator) {
+        transformerHandler.setDocumentLocator(locator);
+    }
+
+    /** {@inheritDoc} */
+    public void startDocument() throws SAXException {
+        transformerHandler.startDocument();
+    }
+
+    /** {@inheritDoc} */
+    public void endDocument() throws SAXException {
+        transformerHandler.endDocument();
+    }
+
+    /** {@inheritDoc} */
+    public void startPrefixMapping(String prefix, String uri) throws SAXException {
+        transformerHandler.startPrefixMapping(prefix, uri);
+    }
+
+    /** {@inheritDoc} */
+    public void endPrefixMapping(String string) throws SAXException {
+        transformerHandler.endPrefixMapping(string);
+    }
+
+    /** {@inheritDoc} */
+    public void startElement(String uri, String localName, String qName, Attributes attrs)
+            throws SAXException {
+        AttributesImpl ai = new AttributesImpl(attrs);
+        transformerHandler.startElement(uri, localName, qName, ai);
+    }
+
+    /** {@inheritDoc} */
+    public void endElement(String uri, String localName, String qName) throws SAXException {
+        transformerHandler.endElement(uri, localName, qName);
+    }
+
+    /** {@inheritDoc} */
+    public void characters(char[] ch, int start, int length) throws SAXException {
+        transformerHandler.characters(ch, start, length);
+    }
+
+    /** {@inheritDoc} */
+    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
+        transformerHandler.ignorableWhitespace(ch, start, length);
+    }
+
+    /** {@inheritDoc} */
+    public void processingInstruction(String target, String data) throws SAXException {
+        transformerHandler.processingInstruction(target, data);
+    }
+
+    /** {@inheritDoc} */
+    public void skippedEntity(String name) throws SAXException {
+        transformerHandler.skippedEntity(name);
+    }
+
+    /** {@inheritDoc} */
+    public void notationDecl(String name, String publicId, String systemId) throws SAXException {
+        transformerHandler.notationDecl(name, publicId, systemId);
+    }
+
+    /** {@inheritDoc} */
+    public void unparsedEntityDecl(String name, String publicId, String systemId,
+            String notationName) throws SAXException {
+        transformerHandler.unparsedEntityDecl(name, publicId, systemId, notationName);
+    }
+
+    /** {@inheritDoc} */
+    public void startDTD(String name, String pid, String lid) throws SAXException {
+        transformerHandler.startDTD(name, pid, lid);
+    }
+
+    /** {@inheritDoc} */
+    public void endDTD() throws SAXException {
+        transformerHandler.endDTD();
+    }
+
+    /** {@inheritDoc} */
+    public void startEntity(String name) throws SAXException {
+        transformerHandler.startEntity(name);
+    }
+
+    /** {@inheritDoc} */
+    public void endEntity(String name) throws SAXException {
+        transformerHandler.endEntity(name);
+    }
+
+    /** {@inheritDoc} */
+    public void startCDATA() throws SAXException {
+        transformerHandler.startCDATA();
+    }
+
+    /** {@inheritDoc} */
+    public void endCDATA() throws SAXException {
+        transformerHandler.endCDATA();
+    }
+
+    /** {@inheritDoc} */
+    public void comment(char[] charArray, int start, int length) throws SAXException {
+        transformerHandler.comment(charArray, start, length);
+    }
+
+}

Property changes on: src/java/org/apache/fop/util/TransformerDefaultHandler.java
___________________________________________________________________
Added: svn:eol-style
   + native
Added: svn:keywords
   + Id

Index: src/documentation/content/xdocs/trunk/accessibility.xml
===================================================================
--- src/documentation/content/xdocs/trunk/accessibility.xml (.../trunk) (revision 0)
+++ src/documentation/content/xdocs/trunk/accessibility.xml (.../branches/Temp_Accessibility) (revision 828760)
@@ -0,0 +1,158 @@
+<?xml version="1.0" standalone="no"?>
+<!--
+  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$ -->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "document-v20.dtd">
+<document>
+  <header>
+    <title>Accessibility</title>
+  </header>
+  <body>
+    <section id="overview">
+      <title>Overview</title>
+      <p>
+        This page describes the
+        <a href="http://en.wikipedia.org/wiki/Accessibility">accessibility</a>
+        features of Apache FOP.
+        <a href="http://www.section508.gov/">Section 508</a> defines accessibility in the context
+        of electronic documents for the US but it impacts also other countries.
+      </p>
+      <p>
+        These features are concentrated exclusively on PDF output
+        (Tagged PDF). There are certain implementation limitations that need to be observed
+        and certain actions are necessary by the content creator to ensure that FOP can create
+        a truly accessible document.
+      </p>
+    </section>
+    <section>
+      <title>Enabling accessibility</title>
+      <p>There are 3 ways to enable accessibility:</p>
+      <ol>
+        <li>
+          <strong>Command line:</strong> The command line option -a turns on accessibility.
+          <code>fop -a -fo mydocument.fo -pdf mydocument.pdf</code>            
+        </li>
+        <li>
+          <strong>Embedding:</strong> <code>userAgent.setAccessibility(true);</code>
+        </li>
+        <li>
+          <strong>Optional setting in fop.xconf file:</strong>
+          <pre>
+          <fop version="1.0">
+              <accessibility>true</accessibility>
+              ...
+          </fop>
+          </pre>
+        </li>
+      </ol>
+      <p>
+        As mentioned, enabling accessibility currently only changes the way PDFs are generated.
+        Internally, FOP maintains a reduced structure tree of the document so the target format
+        viewer can ultimately reconstruct the natural reading order of the document. This is
+        important for document readers that produce an aural representation of the content.
+      </p>
+      <p>
+        Hint: You may need to adjust the Java heap size in order to process larger files.
+      </p>
+    </section>
+    <section id="source">
+      <title>Changes to your XSL-FO input files</title>
+      <p>
+        Apache FOP cannot automatically generate accessible PDFs. Some of the work can only be
+        performed by the content provider. Following are some changes that may be necessary to
+        your XSL-FO content so the generate documents that are truly accessible.
+      </p>
+      <ul>
+        <li>Table cells require a table row as the parent.</li>
+        <li>
+          Ensure that the order of <code>fo:block-container</code> in a page corresponds to
+          the reading order.
+        </li>
+        <li>
+          Alternate text for images: The attribute <code>fox:alt-text</code> has been added
+          for <code>fo:external-graphic</code> and <code>fo:instream-foreign-object</code>.
+        </li>
+        <li>
+          Specify the natural language of the document using the language and country properties
+          (or via the xml:lang shorthand property).
+        </li>
+      </ul>
+    </section>
+    <section id="testing">
+      <title>Testing</title>
+      <p>
+        Accessible PDFs can be tested, for example, using Adobe Acrobat Professional. Its
+        Accessibility Check creates a report indicating any deficiencies with a PDF document.
+        Alternatively, you can just let a screen reader read the document out aloud.
+      </p>
+    </section>
+    <section id="limitations">
+      <title>Limitations</title>
+      <p>
+        Accessibility support in Apache FOP is relatively new, so naturally, there are certain
+        limitations. Please help us identify and close any gaps.
+      </p>
+      <ul>
+        <li>
+          The natural language can currently only be specified on the page-sequence level. The
+          document language is derived from the language of the first page-sequence. It is
+          currently not possible to override the language inside the content below the
+          page-sequence level.
+        </li>
+        <li>
+          It's currently not possible to specify the expanded form of an abbreviation or acronym.
+        </li>
+        <li>
+          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.
+        </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>
+        <li>
+          The accessibility features are only available with PDF output and only if the
+          new output implementation based on the intermediate format (PDFDocumentHandler) is used.
+          Accessibility (Tagged PDF) is not supported by the legacy PDFRenderer.
+        </li>
+      </ul>
+    </section>
+    <section id="links">
+      <title>Related Links</title>
+      <p>
+        We don't provide a comprehensive guide to create accessible documents. Below are some
+        links with additional resources around the topic.
+      </p>
+      <ul>
+        <li><a href="pdfa.html">PDF/A support in Apache FOP</a></li>
+        <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>
+          <a href="http://partners.adobe.com/public/developer/en/pdf/PDFReference.pdf">PDF Reference 1.4</a>
+          (lookup chapters 9.7 "Tagged PDF" and 9.8 "Accessibility Support")
+        </li>
+        <li><a href="http://wiki.apache.org/xmlgraphics-fop/PDF_Accessibility">Developer-oriented details on the accessibility features (on the Wiki)</a></li>
+      </ul>
+    </section>
+  </body>
+</document>

Property changes on: src/documentation/content/xdocs/trunk/accessibility.xml
___________________________________________________________________
Added: svn:eol-style
   + native
Added: svn:keywords
   + Id

Index: src/documentation/content/xdocs/trunk/pdfa.xml
===================================================================
--- src/documentation/content/xdocs/trunk/pdfa.xml (.../trunk) (revision 824832)
+++ src/documentation/content/xdocs/trunk/pdfa.xml (.../branches/Temp_Accessibility) (revision 828760)
@@ -53,8 +53,9 @@
         lack of a full license to get a detailed error protocol.
       </p>
       <p>
-        <strong>PDF/A-1a</strong> is not implemented, yet. This is mostly because of the requirement
-        for tagged PDF which is not available in FOP, yet.
+        <strong>PDF/A-1a</strong> is based on PDF-A-1b and adds accessibility features
+        (such as Tagged PDF). This format is available within the limitation described on
+        the <a href="accessibility.html">Accessibility page</a>.
       </p>
     </section>
     <section id="command-line">
@@ -64,6 +65,9 @@
         as a parameter. If there is a violation of one of the validation rules for
         PDF/A, an error message is presented and the processing stops.
       </p>
+      <p>
+        PDF/A-1a is enabled by specifying "-pdfprofile PDF/A-1a".
+      </p>
     </section>
     <section id="embedded">
       <title>Usage (embedded)</title>
@@ -80,6 +84,9 @@
         If one of the validation rules of PDF/A is violated, an PDFConformanceException
         (descendant of RuntimeException) is thrown.
       </p>
+      <p>
+        For PDF/A-1a, just use the string "PDF/A-1a" instead of "PDF/A-1b".
+      </p>
     </section>
     <section id="rules">
       <title>PDF/A in Action</title>
@@ -118,12 +125,17 @@
           embedded in clear text so non-PDF-aware applications can extract the XMP metadata.
         </li>
       </ul>
+      <note>
+        There are additional requirements if you want to enabled PDF/A-1a (Tagged PDF). This is
+        particularly the specification of the natural language and alternative descriptions for
+        images. Please refer to the <a href="accessibility.html">Accessibility page</a> for details.
+      </note>
     </section>
     <section id="profile-compatibility">
       <title>PDF profile compatibility</title>
       <p>
-        The PDF profiles "PDF/X-3:2003" and "PDF/A-1b" are compatible and can both be
-        activated at the same time.
+        The PDF profiles "PDF/X-3:2003" and "PDF/A-1b" (or "PDF/A-1a") are compatible and can
+        both be activated at the same time.
       </p>
     </section>
     <section id="interoperability">
Index: src/documentation/content/xdocs/site.xml
===================================================================
--- src/documentation/content/xdocs/site.xml (.../trunk) (revision 824832)
+++ src/documentation/content/xdocs/site.xml (.../branches/Temp_Accessibility) (revision 828760)
@@ -159,6 +159,7 @@
       <extensions label="Extensions" href="extensions.html"/>
       <events label="Events" href="events.html"/>
       <metadata label="Metadata" href="metadata.html"/>
+      <accessibility label="Accessibility" href="accessibility.html"/>
     </features>
     
   </trunk>

Property changes on: src/sandbox/org/apache/fop/render/svg/AbstractSVGDocumentHandler.java
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/svg/AbstractSVGDocumentHandler.java:r699793-824832

Index: src/sandbox/org/apache/fop/render/svg/SVGPainter.java
===================================================================
--- src/sandbox/org/apache/fop/render/svg/SVGPainter.java (.../trunk) (revision 824832)
+++ src/sandbox/org/apache/fop/render/svg/SVGPainter.java (.../branches/Temp_Accessibility) (revision 828760)
@@ -324,8 +324,9 @@
     }
 
     /** {@inheritDoc} */
-    public void drawText(int x, int y, int letterSpacing, int wordSpacing, int[] dx, String text)
-                throws IFException {
+
+    public void drawText(int x, int y, int letterSpacing, int wordSpacing, int[] dx,
+            String text) throws IFException {
         try {
             establish(MODE_TEXT);
             AttributesImpl atts = new AttributesImpl();

Property changes on: src/sandbox/org/apache/fop/render/svg/SVGDocumentHandler.java
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/svg/SVGDocumentHandler.java:r699793-824832


Property changes on: examples/embedding/xml/xslt/ifstamp.xsl
___________________________________________________________________
Modified: svn:mergeinfo
   Reverse-merged /xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/examples/embedding/xml/xslt/ifstamp.xsl:r603620-746655


Property changes on: examples/embedding/java/embedding/atxml/ExampleStamp.java
___________________________________________________________________
Modified: svn:mergeinfo
   Reverse-merged /xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/examples/embedding/java/embedding/atxml/ExampleStamp.java:r603620-746655


Property changes on: examples/embedding/java/embedding/atxml/ExampleConcat.java
___________________________________________________________________
Modified: svn:mergeinfo
   Reverse-merged /xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/examples/embedding/java/embedding/atxml/ExampleConcat.java:r603620-746655


Property changes on: .
___________________________________________________________________
Modified: svn:mergeinfo
   Reverse-merged /xmlgraphics/fop/branches/Temp_AreaTreeNewDesign:r603620-745923
   Merged /xmlgraphics/fop/trunk:r603620-824832


Re: [VOTE] Merge the Temp_Accessibility Branch Back to Trunk

by Jeremias Maerki-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I followed what you did in the branch and I like it, although I can't
really follow why accessibility needed to be backported to the old
PDFRenderer. So entirely +1 from me. And thanks for diving into this.
It's good to know that this knowledge has a broader foundation in the
project. And of course, FOP gets exciting new functionality.

On 22.10.2009 18:12:00 Vincent Hennebert wrote:

> Hi,
>
> Work on PDF accessibility is basically done. There are still some tests
> to perform and maybe a few tweaks here and there, but the main
> functionality is in place.
>
> So I’d like to start a vote for merging the branch back to the Trunk:
> https://svn.eu.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_Accessibility
>
> The vote will last the usual 3 days but, since it’s a non-trivial new
> feature, if any committer would like more time to review it, feel free
> to say so and we can extend the vote to 1 week.
>
> Attached is the diff between the branch and the Trunk, if this is of any
> help.
>
> +1 from me.
>
> Thanks,
> Vincent




Jeremias Maerki


Re: [VOTE] Merge the Temp_Accessibility Branch Back to Trunk

by Simon Pepping @ Home :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Oct 22, 2009 at 05:12:00PM +0100, Vincent Hennebert wrote:
> Hi,
>
> Work on PDF accessibility is basically done. There are still some tests
> to perform and maybe a few tweaks here and there, but the main
> functionality is in place.
>
> So I???d like to start a vote for merging the branch back to the Trunk:
> https://svn.eu.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_Accessibility

Can you summarize what the branch tries to achieve?

> The vote will last the usual 3 days but, since it???s a non-trivial new
> feature, if any committer would like more time to review it, feel free
> to say so and we can extend the vote to 1 week.

Can you make that 3 working days?

Simon

--
Simon Pepping
home page: http://www.leverkruid.eu

Re: [VOTE] Merge the Temp_Accessibility Branch Back to Trunk

by Jeremias Maerki-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 22.10.2009 21:15:40 Simon Pepping wrote:

> On Thu, Oct 22, 2009 at 05:12:00PM +0100, Vincent Hennebert wrote:
> > Hi,
> >
> > Work on PDF accessibility is basically done. There are still some tests
> > to perform and maybe a few tweaks here and there, but the main
> > functionality is in place.
> >
> > So I???d like to start a vote for merging the branch back to the Trunk:
> > https://svn.eu.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_Accessibility
>
> Can you summarize what the branch tries to achieve?

I'll try. In short: it provides the Tagged PDF feature that some people
have always wanted.

Long story: Without the accessibility/document structure feature, FOP
simply produces pages with visual content. Visually impaired people need
tools like a screen reader to read document to them. For that the reader
needs to know which parts of a page are important and which are not, and
in which order the elements should be read. It needs to know that a
sentence continues on the next page without stumbling over the page
footer in the middle of the sentence. An image tells a blind person
nothing, so it needs a descriptive text that the screen reader will read
aloud in place of the image. There are laws in various countries that
require certain organizations to produce barrier-free documents. The
accessibility branches' main purpose is just to help with these
requirements.

PDF is the only format we support that has such features. If FOP
implemented PDFXML or XPS, we could later support accessibility there,
too, based on the work started here.

There's another side-effect to tagged PDF: It allows for better text
extraction from the document. PDF even describes ways to make
round-trips from XML -> PDF -> XML -> PDF if certain conditions were met.
However, we don't do that.

Finally, with tagged PDF it is possible to create PDF/A-1a conformant
documents in addition to the PDF/A-1b that we already support. That's
important for long-term archival of documents.

> > The vote will last the usual 3 days but, since it???s a non-trivial new
> > feature, if any committer would like more time to review it, feel free
> > to say so and we can extend the vote to 1 week.
>
> Can you make that 3 working days?

Does that imply you don't work 7 days a week? ;-) Working days are what
we usually apply here, don't we?

> Simon
>
> --
> Simon Pepping
> home page: http://www.leverkruid.eu




Jeremias Maerki


Re: [VOTE] Merge the Temp_Accessibility Branch Back to Trunk

by The Web Maestro :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Sounds like a lofty and honorable goal.

+1 from me.

Clay
--
<the.webmaestro@...> - <http://ourlil.com/>
My religion is simple. My religion is kindness.
- HH The 14th Dalai Lama of Tibet

Re: [VOTE] Merge the Temp_Accessibility Branch Back to Trunk

by cbowditch :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Vincent Hennebert wrote:
> Hi,

Hi Vincent,

>
> Work on PDF accessibility is basically done. There are still some tests
> to perform and maybe a few tweaks here and there, but the main
> functionality is in place.

Thanks for all your hard work getting this feature debugged and cleaned up.

>
> So I’d like to start a vote for merging the branch back to the Trunk:
> https://svn.eu.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_Accessibility
>
> The vote will last the usual 3 days but, since it’s a non-trivial new
> feature, if any committer would like more time to review it, feel free
> to say so and we can extend the vote to 1 week.
>
> Attached is the diff between the branch and the Trunk, if this is of any
> help.
>
> +1 from me.

I've done some local testing with the branch just now and it seems to
work, so +1 from me.

Chris

>
> Thanks,
> Vincent
>


Re: [VOTE] Merge the Temp_Accessibility Branch Back to Trunk

by Adrian Cumiskey-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Vincent,

I've take a look this morning and it looks good from the testing I've
done - it really increases the PDF file size though! :).  +1 from me.

Adrian.

Chris Bowditch wrote:

> Vincent Hennebert wrote:
>> Hi,
>
> Hi Vincent,
>
>>
>> Work on PDF accessibility is basically done. There are still some tests
>> to perform and maybe a few tweaks here and there, but the main
>> functionality is in place.
>
> Thanks for all your hard work getting this feature debugged and
> cleaned up.
>
>>
>> So I’d like to start a vote for merging the branch back to the Trunk:
>> https://svn.eu.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_Accessibility 
>>
>>
>> The vote will last the usual 3 days but, since it’s a non-trivial new
>> feature, if any committer would like more time to review it, feel free
>> to say so and we can extend the vote to 1 week.
>>
>> Attached is the diff between the branch and the Trunk, if this is of any
>> help.
>>
>> +1 from me.
>
> I've done some local testing with the branch just now and it seems to
> work, so +1 from me.
>
> Chris
>
>>
>> Thanks,
>> Vincent
>>
>
>


Re: [VOTE] Merge the Temp_Accessibility Branch Back to Trunk

by Vincent Hennebert-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

Just a few precisions:

Jeremias Maerki wrote:
> On 22.10.2009 21:15:40 Simon Pepping wrote:
<snip/>

>> Can you summarize what the branch tries to achieve?
>
> I'll try. In short: it provides the Tagged PDF feature that some people
> have always wanted.
>
> Long story: Without the accessibility/document structure feature, FOP
> simply produces pages with visual content. Visually impaired people need
> tools like a screen reader to read document to them. For that the reader
> needs to know which parts of a page are important and which are not, and
> in which order the elements should be read. It needs to know that a
> sentence continues on the next page without stumbling over the page
> footer in the middle of the sentence.

This is something that the branch doesn’t actually do yet... The
header/footer will be read at every new page, in the middle of the
sentence.
I don’t know yet how to fix that, and I’m not sure if that should be
done blindly anyway. It could be imagined that in some elaborate layouts
the side-regions have content that the author wants to be read aloud.


<snip/>
> There's another side-effect to tagged PDF: It allows for better text
> extraction from the document. PDF even describes ways to make
> round-trips from XML -> PDF -> XML -> PDF if certain conditions were met.
> However, we don't do that.

Speaking of that, the current code doesn’t insert empty elements (like
<fo:block/>) into the structure tree. The corresponding StructElem
object /is/ created, but is not linked to its parent. Actually it’s
present in the PDF without being referred to by any other object.
I think this is inconsistent, and actually wrong since that would cause
a loss of information possibly needed by a round-trip transformation.
I’m going to change that.


<snip/>
>>> The vote will last the usual 3 days but, since it???s a non-trivial new
>>> feature, if any committer would like more time to review it, feel free
>>> to say so and we can extend the vote to 1 week.
>> Can you make that 3 working days?
>
> Does that imply you don't work 7 days a week? ;-) Working days are what
> we usually apply here, don't we?

Errr... no. At least it’s just by chance if all the votes I’ve launched
so far turned out to last 3 working days. I usually just wait that most
active committers have voted. Speaking of working days doesn’t make much
sense to me anyway since not all committers work on FOP in their day
jobs. Some of them may actually be more active at week-ends.

All that said, I’m happy to make the vote last longer as Simon
requested. And to ensure that it lasts at least 3 working days from now
on.


Vincent

Re: [VOTE] Merge the Temp_Accessibility Branch Back to Trunk

by Jeremias Maerki-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 23.10.2009 13:14:36 Vincent Hennebert wrote:

> Hi,
>
> Just a few precisions:
>
> Jeremias Maerki wrote:
> > On 22.10.2009 21:15:40 Simon Pepping wrote:
> <snip/>
> >> Can you summarize what the branch tries to achieve?
> >
> > I'll try. In short: it provides the Tagged PDF feature that some people
> > have always wanted.
> >
> > Long story: Without the accessibility/document structure feature, FOP
> > simply produces pages with visual content. Visually impaired people need
> > tools like a screen reader to read document to them. For that the reader
> > needs to know which parts of a page are important and which are not, and
> > in which order the elements should be read. It needs to know that a
> > sentence continues on the next page without stumbling over the page
> > footer in the middle of the sentence.
>
> This is something that the branch doesn’t actually do yet... The
> header/footer will be read at every new page, in the middle of the
> sentence.
> I don’t know yet how to fix that, and I’m not sure if that should be
> done blindly anyway. It could be imagined that in some elaborate layouts
> the side-regions have content that the author wants to be read aloud.

Actually, I believe we already do it quite nicely but that there is a
bug in Acrobat's screen reader which doesn't fully rely on the document
structure information, but rather reads through the tag order on each
page which is not what I would expect.

I was just thinking: if PDFBox could be taught to interpret the document
structure information and feed the content to FreeTTS, you'd have a nice
open source PDF reader.

> <snip/>
> > There's another side-effect to tagged PDF: It allows for better text
> > extraction from the document. PDF even describes ways to make
> > round-trips from XML -> PDF -> XML -> PDF if certain conditions were met.
> > However, we don't do that.
>
> Speaking of that, the current code doesn’t insert empty elements (like
> <fo:block/>) into the structure tree. The corresponding StructElem
> object /is/ created, but is not linked to its parent. Actually it’s
> present in the PDF without being referred to by any other object.
> I think this is inconsistent, and actually wrong since that would cause
> a loss of information possibly needed by a round-trip transformation.
> I’m going to change that.

Good catch.

<snip/>



Jeremias Maerki


Inserting Empty Elements Into the Structure Tree [was: Re: [VOTE] Merge the Temp_Accessibility Branch Back to Trunk]

by Vincent Hennebert-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Vincent Hennebert wrote:
> Hi,
>
<snip/>

>> There's another side-effect to tagged PDF: It allows for better text
>> extraction from the document. PDF even describes ways to make
>> round-trips from XML -> PDF -> XML -> PDF if certain conditions were met.
>> However, we don't do that.
>
> Speaking of that, the current code doesn’t insert empty elements (like
> <fo:block/>) into the structure tree. The corresponding StructElem
> object /is/ created, but is not linked to its parent. Actually it’s
> present in the PDF without being referred to by any other object.
> I think this is inconsistent, and actually wrong since that would cause
> a loss of information possibly needed by a round-trip transformation.
> I’m going to change that.

I mean, /at some point/ I’m going to change that...

This is not as easily done as it is said. Take the following example:
<fo:block>
  Before the empty block.
  <fo:block/>
  After the empty block.
</fo:block>

What basically happens currently is that two text drawing requests are
made to the PDF renderer. The renderer creates the appropriate PDF
stream and registers the pieces of text as children of the structure
element corresponding to the outer block. But nothing happens regarding
the inner empty block, since obviously there’s nothing to do.

The structure element for the inner empty block can’t be added to the
outer block’s children at creation time, otherwise the logical order
wouldn’t be followed.

From the quick look I had this is a fundamental limitation of the
current approach. There’s no way to know at which place an empty element
must be inserted into the children list of its parent.

The only way to solve this issue probably is to integrate the handling
of the logical structure into the whole processing chain, passing the
suitable information from the FO tree to the layout engine to the area
tree to the renderer. Probably something that should have been done from
the beginning but this is all but trivial.

Vincent

Re: [VOTE] Merge the Temp_Accessibility Branch Back to Trunk

by Simon Pepping @ Home :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Oct 22, 2009 at 10:36:47PM +0200, Jeremias Maerki wrote:

> On 22.10.2009 21:15:40 Simon Pepping wrote:
> > On Thu, Oct 22, 2009 at 05:12:00PM +0100, Vincent Hennebert wrote:
> > > Hi,
> > >
> > > Work on PDF accessibility is basically done. There are still some tests
> > > to perform and maybe a few tweaks here and there, but the main
> > > functionality is in place.
> > >
> > > So I???d like to start a vote for merging the branch back to the Trunk:
> > > https://svn.eu.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_Accessibility
> >
> > Can you summarize what the branch tries to achieve?
>
> I'll try. In short: it provides the Tagged PDF feature that some people
> have always wanted.

Thanks. That was quite clear. I am not in a position to judge the
quality of the implementation. I welcome this addition to FOP.

I vote +1 to the merger of the Temp_Accessibility branch into trunk.

Simon

--
Simon Pepping
home page: http://www.leverkruid.eu

Re: [VOTE][RESULT] Merge the Temp_Accessibility Branch Back to Trunk

by Vincent Hennebert-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Time to sum up. So we have 6 +1, no other vote. The vote passes.

I’ll proceed with the merge shortly. If you could refrain from
committing anything to the Trunk until then, I would be grateful.


Thanks,
Vincent


Vincent Hennebert wrote:

> Hi,
>
> Work on PDF accessibility is basically done. There are still some tests
> to perform and maybe a few tweaks here and there, but the main
> functionality is in place.
>
> So I’d like to start a vote for merging the branch back to the Trunk:
> https://svn.eu.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_Accessibility
>
> The vote will last the usual 3 days but, since it’s a non-trivial new
> feature, if any committer would like more time to review it, feel free
> to say so and we can extend the vote to 1 week.
>
> Attached is the diff between the branch and the Trunk, if this is of any
> help.
>
> +1 from me.
>
> Thanks,
> Vincent
>