You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by je...@apache.org on 2009/02/19 19:04:51 UTC

svn commit: r745949 [2/3] - in /xmlgraphics/fop/branches/Temp_Accessibility: ./ src/java/META-INF/services/ src/java/org/apache/fop/accessibility/ src/java/org/apache/fop/apps/ src/java/org/apache/fop/area/ src/java/org/apache/fop/cli/ src/java/org/apa...

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFRoot.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFRoot.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFRoot.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFRoot.java Thu Feb 19 18:04:18 2009
@@ -63,7 +63,7 @@
      */
     public PDFRoot(int objnum, PDFPages pages) {
         super();
-        setObjectNumber(objnum);
+         setObjectNumber(objnum);
         put("Type", new PDFName("Catalog"));
         setRootPages(pages);
     }
@@ -252,4 +252,32 @@
         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()
+    }
+
 }

Added: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFStructElem.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFStructElem.java?rev=745949&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFStructElem.java (added)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFStructElem.java Thu Feb 19 18:04:18 2009
@@ -0,0 +1,196 @@
+/*
+ * 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 Structure Element.
+ */
+public class PDFStructElem extends PDFDictionary {
+
+    private PDFObject parentObject = null;
+    private String source = "";
+    private boolean level1 = false;
+
+    /**
+     * Create the /StructTreeRoot dictionary
+     * @param fo passed in fo object
+     * @param parent Parent of this PDFStructElem
+     */
+    public PDFStructElem(String fo, PDFObject parent) {
+        super();
+        if (parent instanceof PDFStructElem) {
+            parentObject = (PDFStructElem) parent;
+        }
+        put("Type", new PDFName("StructElem"));
+        source = fo;
+        //TODO Move this into the render/pdf package. The PDF library shall not contain FO knowledge
+        if ("block".equals(fo)) {
+            put("S", new PDFName("P"));
+        } else if ("inline".equals(fo) || "wrapper".equals(fo) || "character".equals(fo)) {
+            put("S", new PDFName("Span"));
+        } else if ("table-cell".equals(fo)) {
+            PDFStructElem grandParent = (PDFStructElem)
+                ((PDFStructElem)parent).getParentStructElem();
+            String s = grandParent.getSource();
+            if ("table-header".equals(s)) {
+                put("S", new PDFName("TH"));
+            } else {
+                put("S", new PDFName("TD"));
+            }
+        } else if ("table-row".equals(fo)) {
+            put("S", new PDFName("TR"));
+        } else if ("root".equals(fo)) {
+            put("S", new PDFName("Document"));
+        } else if ("page-sequence".equals(fo)) {
+            put("S", new PDFName("Part"));
+        } else if ("flow".equals(fo) || "static-content".equals(fo)) {
+            put("S", new PDFName("Sect"));
+        }   else if ("page-number".equals(fo) || "page-number-citation".equals(fo)
+                || "page-number-citation-last".equals(fo)) {
+            put("S", new PDFName("Quote"));
+        } else if ("external-graphic".equals(fo) || "instream-foreign-object".equals(fo)) {
+            put("S", new PDFName("Figure"));
+        } else if ("table".equals(fo)) {
+            put("S", new PDFName("Table"));
+        } else if ("table-body".equals(fo)) {
+            put("S", new PDFName("TBody"));
+        } else if ("table-header".equals(fo)) {
+            put("S", new PDFName("THead"));
+        } else if ("table-footer".equals(fo)) {
+            put("S", new PDFName("TFoot"));
+        }  else if ("list-block".equals(fo)) {
+            put("S", new PDFName("L"));
+        } else if ("list-item".equals(fo)) {
+            put("S", new PDFName("LI"));
+        } else if ("list-item-label".equals(fo)) {
+            put("S", new PDFName("Lbl"));
+        } else if ("list-item-body".equals(fo)) {
+            put("S", new PDFName("LBody"));
+        } else if ("block-container".equals(fo)) {
+            put("S", new PDFName("Div"));
+        } else if ("basic-link".equals(fo)) {
+            put("S", new PDFName("Link"));
+        } else if ("footnote".equals(fo)) {
+            put("S", new PDFName("Note"));
+        } else if ("footnote-body".equals(fo)) {
+            put("S", new PDFName("Sect"));
+        } else if ("marker".equals(fo)) {
+            put("S", new PDFName("Private"));
+        }  else {
+            log.error("Accessibility: PDFStructElem constructor is missing: " + fo);
+        }
+        setParent(parent);
+        if (!"external-graphic".equals(fo) && !"instream-foreign-object".equals(fo)) {
+            put("K", new PDFArray());
+        }
+    }
+
+    /**
+     * This method is called for PDFStructElements which are direct children of
+     * fo:static-content or fo:flow-section
+     */
+    public void setLevel1() {
+        this.level1 = true;
+    }
+
+    /**
+     *
+     * @return true if the PDFStructElement is a direct child of
+     * fo:static-content or fo:flow-section
+     */
+    public boolean getLevel1() {
+        return this.level1;
+    }
+
+    /**
+     * Get the parent
+     * @return PDFStructElem of parent
+     */
+    public PDFObject getParentStructElem() {
+        return (PDFStructElem)this.parentObject;
+    }
+
+    /**
+     * Set the parent for this StructElem
+     * @param parent to be added
+     */
+    public void setParent(PDFObject parent) {
+        if (parent != null) {
+           put("P", new PDFReference(parent));
+        }
+    }
+
+    /**
+     * Get the source of this StructElem
+     * @return the source
+     */
+    public String getSource() {
+        return source;
+    }
+
+    /**
+     * The kids of this StructElem
+     * @return the kids
+     */
+    public PDFArray getKids() {
+        return (PDFArray)get("K");
+    }
+
+    /**
+     * Add a kid to this strucElem
+     * @param kid to be added
+     */
+    public void addKid(PDFObject kid) {
+        getKids().add(kid);
+    }
+
+    /**
+     * Add a kid, but only if it does not already exist
+     * @param kid to be added
+     * @return true if kid did not already exist
+     */
+    public boolean addUniqueKid(PDFObject kid) {
+        PDFArray mArray = getKids();
+        if (!mArray.contains(kid)) {
+            getKids().add(kid);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Add kid referenced through mcid integer
+     * used fo:external-graphic
+     * @param mcid of this kid
+     */
+    public void addMCIDKid(int mcid) {
+        put("K", mcid);
+    }
+
+    /**
+     * Add a page reference to this structElem
+     * @param pageObject to be added
+     */
+    public void addPage(Object pageObject) {
+        put("Pg", (PDFObject) pageObject);
+    }
+
+}

Propchange: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFStructElem.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFStructElem.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFStructTreeRoot.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFStructTreeRoot.java?rev=745949&view=auto
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFStructTreeRoot.java (added)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFStructTreeRoot.java Thu Feb 19 18:04:18 2009
@@ -0,0 +1,67 @@
+/*
+ * 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 {
+
+    /**
+     * Create the /StructTreeRoot dictionary.
+     */
+    public PDFStructTreeRoot() {
+        super();
+        put("Type", new PDFName("StructTreeRoot"));
+        put("K", new PDFArray());
+    }
+
+    /**
+     * Add parentTree entry.
+     * @param parentTree to be added
+     */
+    public void addParentTree(PDFParentTree parentTree) {
+        put("ParentTree", parentTree);
+    }
+
+    /**
+     * Get the kids.
+     * @return the kids
+     */
+    public PDFArray getKids() {
+        return (PDFArray)get("K");
+    }
+
+    /**
+     * Returns the first child of the kids array (normally the structure tree root element)
+     * @return the first child
+     */
+    public PDFObject getFirstChild() {
+        return (PDFObject)getKids().get(0);
+    }
+
+    /**
+     * Adds a kid.
+     * @param kid to be added
+     */
+    public void addKid(PDFObject kid) {
+        getKids().add(kid);
+    }
+}
\ No newline at end of file

Propchange: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFStructTreeRoot.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFStructTreeRoot.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFTextUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFTextUtil.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFTextUtil.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/pdf/PDFTextUtil.java Thu Feb 19 18:04:18 2009
@@ -48,6 +48,7 @@
     public static final int TR_CLIP = 7;
 
     private boolean inTextObject = false;
+    private boolean artifactMode = false;
     private String startText;
     private String endText;
     private boolean useMultiByte;
@@ -116,6 +117,15 @@
     }
 
     /**
+     * Indicates whether we are in a text object and if that text object represents
+     * an artifact.
+     * @return true if in artifact-mode text object
+     */
+    public boolean inArtifactMode() {
+        return this.artifactMode;
+    }
+
+    /**
      * Called when a new text object should be started. Be sure to call setFont() before
      * issuing any text painting commands.
      */
@@ -128,11 +138,51 @@
     }
 
     /**
+     * Begin of a regular text object, used for accessibility
+     * @param mcid of text object
+     * @param structElemType of parent
+     */
+    public void beginTextObjectAccess(int mcid, String structElemType) {
+        if (inTextObject) {
+            throw new IllegalStateException("Already in text object");
+        }
+           write(structElemType + " <</MCID "
+                   + String.valueOf(mcid) + ">>\nBDC\nBT\n");
+        this.inTextObject = true;
+    }
+
+    /**
+     * Begin of a text object marked as artifact (fo:leader in XSL-FO) text object.
+     * Used for accessibility.
+     */
+    public void beginArtifactTextObject() {
+        if (inTextObject) {
+            throw new IllegalStateException("Already in text object");
+        }
+        write("/Artifact\nBMC\nBT\n");
+        this.inTextObject = true;
+        this.artifactMode = true;
+    }
+
+    /**
      * Called when a text object should be ended.
      */
     public void endTextObject() {
+        endTextObject(false);
+    }
+
+    /**
+     * Called when a text object should be ended.
+     * @param accessEnabled indicating if accessibility is turned on or not
+     */
+    public void endTextObject(boolean accessEnabled) {
         checkInTextObject();
-        write("ET\n");
+        if (accessEnabled) {
+            write("ET\nEMC\n");
+        } else {
+            write("ET\n");
+        }
+        this.artifactMode = false;
         this.inTextObject = false;
         initValues();
     }

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java Thu Feb 19 18:04:18 2009
@@ -834,8 +834,10 @@
      * @param url the URI/URL of the image
      * @param pos the position of the image
      * @param foreignAttributes an optional Map with foreign attributes, may be null
+     * @param ptr used for accessibility
      */
-    protected abstract void drawImage(String url, Rectangle2D pos, Map foreignAttributes);
+    protected abstract void drawImage(String url, Rectangle2D pos, Map foreignAttributes, 
+            String ptr);
 
     /**
      * Draw an image at the indicated location.
@@ -843,7 +845,7 @@
      * @param pos the position of the image
      */
     protected final void drawImage(String url, Rectangle2D pos) {
-        drawImage(url, pos, null);
+        drawImage(url, pos, null, "");
     }
 
     /**

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/AbstractRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/AbstractRenderer.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/AbstractRenderer.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/AbstractRenderer.java Thu Feb 19 18:04:18 2009
@@ -737,11 +737,13 @@
         currentBPPosition += viewport.getOffset();
         Rectangle2D contpos = viewport.getContentPosition();
         if (content instanceof Image) {
-            renderImage((Image) content, contpos);
+            String ptr = (String) viewport.getTrait(Trait.PTR);
+            renderImage((Image) content, contpos, ptr);
         } else if (content instanceof Container) {
             renderContainer((Container) content);
         } else if (content instanceof ForeignObject) {
-            renderForeignObject((ForeignObject) content, contpos);
+            String ptr = (String) viewport.getTrait(Trait.PTR);
+            renderForeignObject((ForeignObject) content, contpos, ptr);
         } else if (content instanceof InlineBlockParent) {
             renderInlineBlockParent((InlineBlockParent) content);
         }
@@ -754,9 +756,10 @@
      *
      * @param image  The image
      * @param pos    The target position of the image
+     * @param ptr  used for accessibility
      * (todo) Make renderImage() protected
      */
-    public void renderImage(Image image, Rectangle2D pos) {
+    public void renderImage(Image image, Rectangle2D pos, String ptr) {
         // Default: do nothing.
         // Some renderers (ex. Text) don't support images.
     }
@@ -780,9 +783,10 @@
      *
      * @param fo   The foreign object area
      * @param pos  The target position of the foreign object
+     * @param ptr  used for accessibility
      * (todo) Make renderForeignObject() protected
      */
-    protected void renderForeignObject(ForeignObject fo, Rectangle2D pos) {
+    protected void renderForeignObject(ForeignObject fo, Rectangle2D pos, String ptr) {
         // Default: do nothing.
         // Some renderers (ex. Text) don't support foreign objects.
     }

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/afp/AFPPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/afp/AFPPainter.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/afp/AFPPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/afp/AFPPainter.java Thu Feb 19 18:04:18 2009
@@ -183,7 +183,7 @@
     }
 
     /** {@inheritDoc} */
-    public void drawImage(String uri, Rectangle rect) throws IFException {
+    public void drawImage(String uri, Rectangle rect, String ptr) throws IFException {
         String name = documentHandler.getPageSegmentNameFor(uri);
         if (name != null) {
             float[] srcPts = {rect.x, rect.y};
@@ -195,7 +195,7 @@
     }
 
     /** {@inheritDoc} */
-    public void drawImage(Document doc, Rectangle rect) throws IFException {
+    public void drawImage(Document doc, Rectangle rect, String ptr) throws IFException {
         drawImageUsingDocument(doc, rect);
     }
 
@@ -312,7 +312,7 @@
     /** {@inheritDoc} */
     public void drawText(int x, int y,
             final int letterSpacing, final int wordSpacing, final int[] dx,
-            final String text) throws IFException {
+            final String text, final String ptr) throws IFException {
         final int fontSize = this.state.getFontSize();
         getPaintingState().setFontSize(fontSize);
 

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/afp/AFPRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/afp/AFPRenderer.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/afp/AFPRenderer.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/afp/AFPRenderer.java Thu Feb 19 18:04:18 2009
@@ -375,7 +375,7 @@
         ImageFlavor.GRAPHICS2D, ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE };
 
     /** {@inheritDoc} */
-    public void drawImage(String uri, Rectangle2D pos, Map foreignAttributes) {
+    public void drawImage(String uri, Rectangle2D pos, Map foreignAttributes, String ptr) {
         uri = URISpecification.getURL(uri);
         paintingState.setImageUri(uri);
 
@@ -506,7 +506,7 @@
 
     /** {@inheritDoc} */
     public void renderImage(Image image, Rectangle2D pos) {
-        drawImage(image.getURL(), pos, image.getForeignAttributes());
+        drawImage(image.getURL(), pos, image.getForeignAttributes(),"");
     }
 
     /** {@inheritDoc} */

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFConstants.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFConstants.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFConstants.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFConstants.java Thu Feb 19 18:04:18 2009
@@ -50,4 +50,6 @@
     String EL_BORDER_RECT = "border-rect";
     String EL_FONT = "font";
     String EL_TEXT = "text";
+    /** used for accessibility */
+    String EL_STRUCTURE_TREE = "structure-tree";  
 }

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFPainter.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFPainter.java Thu Feb 19 18:04:18 2009
@@ -153,10 +153,11 @@
      * @param wordSpacing additional spacing between words (may be 0)
      * @param dx an array of adjustment values for each character in X-direction (may be null)
      * @param text the text
+     * @param ptr used for accessibility
      * @throws IFException if an error occurs while handling this event
      */
     void drawText(int x, int y, int letterSpacing, int wordSpacing,
-            int[] dx, String text) throws IFException;
+            int[] dx, String text, String ptr) throws IFException;
 
     /**
      * Restricts the current clipping region with the given rectangle.
@@ -205,18 +206,20 @@
      * an fo:external-graphic in XSL-FO.
      * @param uri the image's URI
      * @param rect the rectangle in which the image shall be painted
+     * @param ptr used for accessibility
      * @throws IFException if an error occurs while handling this event
      */
-    void drawImage(String uri, Rectangle rect) throws IFException;
+    void drawImage(String uri, Rectangle rect, String ptr) throws IFException;
 
     /**
      * Draws an image (represented by a DOM document) inside a given rectangle. This is the
      * equivalent to an fo:instream-foreign-object in XSL-FO.
      * @param doc the DOM document containing the foreign object
      * @param rect the rectangle in which the image shall be painted
+     * @param ptr used for accessibility 
      * @throws IFException if an error occurs while handling this event
      */
-    void drawImage(Document doc, Rectangle rect) throws IFException;
+    void drawImage(Document doc, Rectangle rect, String ptr) throws IFException;
     //Note: For now, all foreign objects are handled as DOM documents. At the moment, all known
     //implementations use a DOM anyway, so optimizing this to work with SAX wouldn't result in
     //any performance benefits. The IFRenderer itself has a DOM anyway. Only the IFParser could

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFParser.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFParser.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFParser.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFParser.java Thu Feb 19 18:04:18 2009
@@ -481,7 +481,8 @@
                 s = lastAttributes.getValue("word-spacing");
                 int wordSpacing = (s != null ? Integer.parseInt(s) : 0);
                 int[] dx = XMLUtil.getAttributeAsIntArray(lastAttributes, "dx");
-                painter.drawText(x, y, letterSpacing, wordSpacing, dx, content.toString());
+                String ptr = lastAttributes.getValue("ptr"); // used for accessibility
+                painter.drawText(x, y, letterSpacing, wordSpacing, dx, content.toString(), ptr);
             }
 
             public boolean ignoreCharacters() {
@@ -576,9 +577,10 @@
                 int height = Integer.parseInt(lastAttributes.getValue("height"));
                 Map foreignAttributes = getForeignAttributes(lastAttributes);
                 establishForeignAttributes(foreignAttributes);
+                String ptr = lastAttributes.getValue("ptr"); // used for accessibility
                 if (foreignObject != null) {
                     painter.drawImage(foreignObject,
-                            new Rectangle(x, y, width, height));
+                            new Rectangle(x, y, width, height), ptr);
                     foreignObject = null;
                 } else {
                     String uri = lastAttributes.getValue(
@@ -586,7 +588,7 @@
                     if (uri == null) {
                         throw new IFException("xlink:href is missing on image", null);
                     }
-                    painter.drawImage(uri, new Rectangle(x, y, width, height));
+                    painter.drawImage(uri, new Rectangle(x, y, width, height), ptr);
                 }
                 resetForeignAttributes();
                 inForeignObject = false;

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFRenderer.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFRenderer.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFRenderer.java Thu Feb 19 18:04:18 2009
@@ -818,7 +818,7 @@
             currentIPPosition = saveIP;
             currentBPPosition = saveBP;
 
-            currentBPPosition += (int)(bv.getAllocBPD());
+            currentBPPosition += (bv.getAllocBPD());
         }
         viewportDimensionStack.pop();
     }
@@ -886,6 +886,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();
@@ -929,6 +930,7 @@
 
         // warn if link trait found but not allowed, else create link
         if (linkTraitFound) {
+            action.setPtr(ptr);  // used for accessibility
             Link link = new Link(action, ipRect);
             this.deferredLinks.add(link);
         }
@@ -963,6 +965,7 @@
 
         String fontName = getInternalFontNameForArea(text);
         int size = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue();
+        String ptr = (String)text.getTrait(Trait.PTR); // used for accessibility
 
         // This assumes that *all* CIDFonts use a /ToUnicode mapping
         Typeface tf = getTypeface(fontName);
@@ -981,7 +984,7 @@
         textUtil.setStartPosition(rx, bl);
         textUtil.setSpacing(text.getTextLetterSpaceAdjust(), text.getTextWordSpaceAdjust());
         super.renderText(text);
-
+        textUtil.setPtr(ptr); // used for accessibility
         textUtil.flush();
         renderTextDecoration(tf, size, text, bl, rx);
     }
@@ -1054,15 +1057,24 @@
         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;
+        private String ptr = null; // used for accessibility
 
         void addChar(char ch) {
             text.append(ch);
         }
 
+        /**
+         * used for accessibility
+         * @param inPtr to be stored
+         */
+        public void setPtr(String inPtr) {
+            ptr = inPtr;
+        }
+
         void adjust(int adjust) {
             if (adjust != 0) {
                 int idx = text.length();
@@ -1105,9 +1117,9 @@
                         System.arraycopy(dx, 0, effDX, 0, size);
                     }
                     if (combined) {
-                        painter.drawText(startx, starty, 0, 0, effDX, text.toString());
+                        painter.drawText(startx, starty, 0, 0, effDX, text.toString(), ptr);
                     } else {
-                        painter.drawText(startx, starty, tls, tws, effDX, text.toString());
+                        painter.drawText(startx, starty, tls, tws, effDX, text.toString(), ptr);
                     }
                 } catch (IFException e) {
                     handleIFException(e);
@@ -1118,12 +1130,12 @@
     }
 
     /** {@inheritDoc} */
-    public void renderImage(Image image, Rectangle2D pos) {
-        drawImage(image.getURL(), pos, image.getForeignAttributes());
+    public void renderImage(Image image, Rectangle2D pos, String ptr) {
+        drawImage(image.getURL(), pos, image.getForeignAttributes(), ptr);
     }
 
     /** {@inheritDoc} */
-    protected void drawImage(String uri, Rectangle2D pos, Map foreignAttributes) {
+    protected void drawImage(String uri, Rectangle2D pos, Map foreignAttributes, String ptr) {
         Rectangle posInt = new Rectangle(
                 currentIPPosition + (int)pos.getX(),
                 currentBPPosition + (int)pos.getY(),
@@ -1132,7 +1144,7 @@
         uri = URISpecification.getURL(uri);
         try {
             establishForeignAttributes(foreignAttributes);
-            painter.drawImage(uri, posInt);
+            painter.drawImage(uri, posInt, ptr);
             resetForeignAttributes();
         } catch (IFException ife) {
             handleIFException(ife);
@@ -1140,7 +1152,7 @@
     }
 
     /** {@inheritDoc} */
-    public void renderForeignObject(ForeignObject fo, Rectangle2D pos) {
+    public void renderForeignObject(ForeignObject fo, Rectangle2D pos, String ptr) {
         endTextObject();
         Rectangle posInt = new Rectangle(
                 currentIPPosition + (int)pos.getX(),
@@ -1150,7 +1162,7 @@
         Document doc = fo.getDocument();
         try {
             establishForeignAttributes(fo.getForeignAttributes());
-            painter.drawImage(doc, posInt);
+            painter.drawImage(doc, posInt, ptr);
             resetForeignAttributes();
         } catch (IFException ife) {
             handleIFException(ife);

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFSerializer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFSerializer.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFSerializer.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/IFSerializer.java Thu Feb 19 18:04:18 2009
@@ -25,11 +25,24 @@
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.geom.AffineTransform;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
 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;
@@ -60,10 +73,46 @@
         implements IFConstants, IFPainter, IFDocumentNavigationHandler {
 
     private IFDocumentHandler mimicHandler;
+    private int pageSequenceCounter; // used for accessibility
+    private DocumentBuilder parser = null; // used for accessibility
+    private Document doc = null;  // used for accessibility
 
     /** Holds the intermediate format state */
     private IFState state;
 
+    private static class NamespaceContextImpl implements NamespaceContext {
+
+         public String uri;
+         public String prefix;
+
+         public NamespaceContextImpl() {
+         }
+
+         public NamespaceContextImpl(String prefix, String uri) {
+             this.uri = uri;
+             this.prefix = prefix;
+            }
+
+         public String getNamespaceURI(String prefix) {
+           return uri;
+         }
+         public void setNamespaceURI(String uri) {
+           this.uri = uri;
+         }
+
+         public String getPrefix(String uri) {
+           return prefix;
+         }
+
+         public void setPrefix(String prefix) {
+           this.prefix = prefix;
+         }
+         public Iterator getPrefixes(String uri) {
+             return null;
+         }
+
+    }
+
     /**
      * Default constructor.
      */
@@ -151,8 +200,16 @@
             handler.startPrefixMapping(DocumentNavigationExtensionConstants.PREFIX,
                     DocumentNavigationExtensionConstants.NAMESPACE);
             handler.startElement(EL_DOCUMENT);
+            if (this.getUserAgent().accessibilityEnabled()) {
+                pageSequenceCounter = 0;
+                DocumentBuilderFactory  factory = DocumentBuilderFactory.newInstance();
+                factory.setNamespaceAware(true);
+                parser = factory.newDocumentBuilder();
+            }
         } catch (SAXException e) {
             throw new IFException("SAX error in startDocument()", e);
+        } catch (ParserConfigurationException pce) {
+            throw new IFException("Error creating new DocumentBuilder", pce);
         }
     }
 
@@ -210,9 +267,33 @@
             if (id != null) {
                 atts.addAttribute(XML_NAMESPACE, "id", "xml:id", XMLUtil.CDATA, id);
             }
+
             handler.startElement(EL_PAGE_SEQUENCE, atts);
+            if (this.getUserAgent().accessibilityEnabled()) {
+                if (doc == null) {
+                    doc = parser.parse(
+                            new ByteArrayInputStream(this.getUserAgent().getReducedFOTree()));
+                }
+                handler.startElement(EL_STRUCTURE_TREE); // add structure tree
+                String xpathExpr
+                   = "/fo:root/fo:page-sequence[" + Integer.toString(++pageSequenceCounter) + "]/*";
+                XPath xpath = XPathFactory.newInstance().newXPath();
+                NamespaceContext namespaceContext
+                    = new NamespaceContextImpl("fo", "http://www.w3.org/1999/XSL/Format");
+                xpath.setNamespaceContext(namespaceContext);
+                NodeList nodes = (NodeList)xpath.evaluate(xpathExpr, doc, XPathConstants.NODESET);
+                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);
+        } catch (XPathExpressionException e) {
+            throw new IFException("Error while evaluating XPath expression", e);
+        } catch (IOException ioe) {
+            throw new IFException("I/O error while parsing structure tree", ioe);
         }
     }
 
@@ -285,6 +366,7 @@
     public void startPageTrailer() throws IFException {
         try {
             handler.startElement(EL_PAGE_TRAILER);
+            commitNavigation();
         } catch (SAXException e) {
             throw new IFException("SAX error in startPageTrailer()", e);
         }
@@ -293,7 +375,6 @@
     /** {@inheritDoc} */
     public void endPageTrailer() throws IFException {
         try {
-            commitNavigation();
             handler.endElement(EL_PAGE_TRAILER);
         } catch (SAXException e) {
             throw new IFException("SAX error in endPageTrailer()", e);
@@ -382,7 +463,7 @@
     }
 
     /** {@inheritDoc} */
-    public void drawImage(String uri, Rectangle rect) throws IFException {
+    public void drawImage(String uri, Rectangle rect, String ptr) throws IFException {
         try {
             AttributesImpl atts = new AttributesImpl();
             addAttribute(atts, XLINK_HREF, uri);
@@ -391,6 +472,9 @@
             addAttribute(atts, "width", Integer.toString(rect.width));
             addAttribute(atts, "height", Integer.toString(rect.height));
             addForeignAttributes(atts);
+            if (ptr != null) {
+                addAttribute(atts, "ptr", ptr);  // used for accessibility
+            }
             handler.element(EL_IMAGE, atts);
         } catch (SAXException e) {
             throw new IFException("SAX error in startGroup()", e);
@@ -409,7 +493,7 @@
     }
 
     /** {@inheritDoc} */
-    public void drawImage(Document doc, Rectangle rect) throws IFException {
+    public void drawImage(Document doc, Rectangle rect, String ptr) throws IFException {
         try {
             AttributesImpl atts = new AttributesImpl();
             addAttribute(atts, "x", Integer.toString(rect.x));
@@ -417,6 +501,9 @@
             addAttribute(atts, "width", Integer.toString(rect.width));
             addAttribute(atts, "height", Integer.toString(rect.height));
             addForeignAttributes(atts);
+            if (ptr != null) {
+                addAttribute(atts, "ptr", ptr);  // used for accessibility
+            }
             handler.startElement(EL_IMAGE, atts);
             new DOM2SAX(handler).writeDocument(doc, true);
             handler.endElement(EL_IMAGE);
@@ -515,7 +602,7 @@
 
     /** {@inheritDoc} */
     public void drawText(int x, int y, int letterSpacing, int wordSpacing,
-            int[] dx, String text) throws IFException {
+            int[] dx, String text, String ptr) throws IFException {
         try {
             AttributesImpl atts = new AttributesImpl();
             XMLUtil.addAttribute(atts, XMLConstants.XML_SPACE, "preserve");
@@ -530,6 +617,9 @@
             if (dx != null) {
                 addAttribute(atts, "dx", IFUtil.toString(dx));
             }
+            if (ptr != null) {
+                addAttribute(atts, "ptr", ptr);  // used for accessibility
+            }
             handler.startElement(EL_TEXT, atts);
             char[] chars = text.toCharArray();
             handler.characters(chars, 0, chars.length);

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/extensions/AbstractAction.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/extensions/AbstractAction.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/extensions/AbstractAction.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/intermediate/extensions/AbstractAction.java Thu Feb 19 18:04:18 2009
@@ -27,6 +27,7 @@
 public abstract class AbstractAction implements XMLizable {
 
     private String id;
+    private String ptr; // used for accessibility
 
     /**
      * Sets an ID to make the action referencable.
@@ -43,7 +44,23 @@
     public String getID() {
         return this.id;
     }
-
+    
+    /**
+     * Used for accessibility   
+     * @param s representing the ptr
+     */
+    public void setPtr(String s) {
+        this.ptr = s;
+    }
+    
+    /**
+     * Used for accessibility
+     * @return the ptr
+     */
+    public String getPtr() {
+        return this.ptr;
+    }
+    
     /**
      * Indicates whether the action has an ID and is therefore referencable.
      * @return true if the action has an ID

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/java2d/Java2DPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/java2d/Java2DPainter.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/java2d/Java2DPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/java2d/Java2DPainter.java Thu Feb 19 18:04:18 2009
@@ -156,7 +156,7 @@
     }
 
     /** {@inheritDoc} */
-    public void drawImage(String uri, Rectangle rect) throws IFException {
+    public void drawImage(String uri, Rectangle rect, String ptr) throws IFException {
         drawImageUsingURI(uri, rect);
     }
 
@@ -168,7 +168,7 @@
     }
 
     /** {@inheritDoc} */
-    public void drawImage(Document doc, Rectangle rect) throws IFException {
+    public void drawImage(Document doc, Rectangle rect, String ptr) throws IFException {
         drawImageUsingDocument(doc, rect);
     }
 
@@ -208,7 +208,7 @@
     }
 
     /** {@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, String ptr)
             throws IFException {
         g2dState.updateColor(state.getTextColor());
         FontTriplet triplet = new FontTriplet(

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/java2d/Java2DRenderer.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/java2d/Java2DRenderer.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/java2d/Java2DRenderer.java Thu Feb 19 18:04:18 2009
@@ -875,7 +875,7 @@
                                                       ImageFlavor.XML_DOM};
 
     /** {@inheritDoc} */
-    protected void drawImage(String uri, Rectangle2D pos, Map foreignAttributes) {
+    protected void drawImage(String uri, Rectangle2D pos, Map foreignAttributes, String ptr) {
 
         int x = currentIPPosition + (int)Math.round(pos.getX());
         int y = currentBPPosition + (int)Math.round(pos.getY());

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pcl/PCLPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pcl/PCLPainter.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pcl/PCLPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pcl/PCLPainter.java Thu Feb 19 18:04:18 2009
@@ -154,7 +154,7 @@
     }
 
     /** {@inheritDoc} */
-    public void drawImage(String uri, Rectangle rect) throws IFException {
+    public void drawImage(String uri, Rectangle rect, String ptr) throws IFException {
         drawImageUsingURI(uri, rect);
     }
 
@@ -176,7 +176,7 @@
     }
 
     /** {@inheritDoc} */
-    public void drawImage(Document doc, Rectangle rect) throws IFException {
+    public void drawImage(Document doc, Rectangle rect, String ptr) throws IFException {
         drawImageUsingDocument(doc, rect);
     }
 
@@ -312,8 +312,9 @@
     }
 
     /** {@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, String ptr)
                 throws IFException {
+        //Note: ptr is ignored as it is only needed for accessibility
         try {
             FontTriplet triplet = new FontTriplet(
                     state.getFontFamily(), state.getFontStyle(), state.getFontWeight());
@@ -474,7 +475,7 @@
                 Java2DPainter painter = new Java2DPainter(g2d,
                         getContext(), parent.getFontInfo(), state);
                 try {
-                    painter.drawText(x, y, letterSpacing, wordSpacing, dx, text);
+                    painter.drawText(x, y, letterSpacing, wordSpacing, dx, text, "");
                 } catch (IFException e) {
                     //This should never happen with the Java2DPainter
                     throw new RuntimeException("Unexpected error while painting text", e);

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java Thu Feb 19 18:04:18 2009
@@ -49,4 +49,6 @@
      * PDF/X profile is active).
      */
     String KEY_DISABLE_SRGB_COLORSPACE = "disable-srgb-colorspace";
+    /** PDF Accessibility */
+    String ACCESSIBLITY = "accessibility";
 }

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java Thu Feb 19 18:04:18 2009
@@ -50,6 +50,7 @@
 
     /** the current stream to add PDF commands to */
     private PDFStream currentStream;
+    private boolean accessEnabled; // used for accessibility
 
     /** drawing state */
     protected PDFPaintingState currentState = null;
@@ -63,9 +64,10 @@
      * @param document the PDF document
      * @param out the output stream the PDF document is generated to
      * @param resourceContext the resource context
+     * @param accessibilityEnabled indicating if accessibility is enabled or not
      */
     public PDFContentGenerator(PDFDocument document, OutputStream out,
-            PDFResourceContext resourceContext) {
+            PDFResourceContext resourceContext, boolean accessibilityEnabled) {
         this.document = document;
         this.outputStream = out;
         this.resourceContext = resourceContext;
@@ -78,6 +80,7 @@
         };
 
         this.currentState = new PDFPaintingState();
+        this.accessEnabled = accessibilityEnabled;
     }
 
     /**
@@ -153,6 +156,23 @@
         currentStream.add("q\n");
     }
 
+    /** {@inheritDoc} */
+    protected void saveGraphicsState(String structElemType, int sequenceNum) {
+        endTextObject();
+        currentState.save();
+        startAccessSequence(structElemType, sequenceNum);
+        currentStream.add("q\n");
+    }
+
+    /**
+     * Used for accessibility
+     * @param structElemType Structure Element Type
+     * @param sequenceNum    Sequence number
+     */
+    protected void startAccessSequence(String structElemType, int sequenceNum) {
+        currentStream.add(structElemType + " <</MCID " + String.valueOf(sequenceNum) + ">>\nBDC\n");
+    }
+
     /**
      * Restored the graphics state valid before the previous {@code #saveGraphicsState()}.
      * @param popState true if the state should also be popped, false if only the PDF command
@@ -171,6 +191,35 @@
         restoreGraphicsState(true);
     }
 
+    /** used for accessibility */
+    protected void restoreGraphicsStateAccess() {
+        endTextObject();
+        currentStream.add("Q\n");
+        currentStream.add("EMC\n");
+        currentState.restore();
+    }
+
+    /**
+     * used for accessibility, separates 2 text elements
+     * @param mcid of new text element
+     * @param structElemType of parent of new text element
+     */
+    protected void separateTextElements(int mcid, String structElemType) {
+        textutil.endTextObject(true);
+        textutil.beginTextObjectAccess(mcid, structElemType);
+    }
+
+    /**
+     * used for accessibility
+     * separates a text element from fo:leader text element
+     */
+    public void separateTextElementFromLeader() {
+        if (!textutil.inArtifactMode()) {
+            textutil.endTextObject(true);
+            textutil.beginArtifactTextObject();
+        }
+    }
+
     /** Indicates the beginning of a text object. */
     protected void beginTextObject() {
         if (!textutil.isInTextObject()) {
@@ -178,10 +227,30 @@
         }
     }
 
+    /**
+     * Accessibility beginTextObject
+     * @param mcid of text element
+     * @param structElemType of parent
+     */
+    protected void beginTextObjectAccess(int mcid, String structElemType) {
+        if (!textutil.isInTextObject()) {
+            textutil.beginTextObjectAccess(mcid, structElemType);
+        }
+    }
+
+    /**
+     * Accessibility begin of LeaderTextObject
+     */
+    public void beginLeaderTextObject() {
+        if (!textutil.isInTextObject()) {
+            textutil.beginArtifactTextObject();
+        }
+    }
+
     /** Indicates the end of a text object. */
     protected void endTextObject() {
         if (textutil.isInTextObject()) {
-            textutil.endTextObject();
+            textutil.endTextObject(accessEnabled);
         }
     }
 
@@ -326,5 +395,26 @@
         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
+     * @param structElemType of this image
+     * @param mcid of this image
+     */
+    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();
+    }
 
 }

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java Thu Feb 19 18:04:18 2009
@@ -21,9 +21,28 @@
 
 import java.awt.Dimension;
 import java.awt.geom.AffineTransform;
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.xml.sax.SAXException;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -32,11 +51,19 @@
 import org.apache.fop.apps.MimeConstants;
 import org.apache.fop.fo.extensions.xmp.XMPMetadata;
 import org.apache.fop.pdf.PDFAnnotList;
+import org.apache.fop.pdf.PDFArray;
+import org.apache.fop.pdf.PDFDictionary;
 import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.pdf.PDFName;
+import org.apache.fop.pdf.PDFNumsArray;
+import org.apache.fop.pdf.PDFObject;
 import org.apache.fop.pdf.PDFPage;
+import org.apache.fop.pdf.PDFParentTree;
 import org.apache.fop.pdf.PDFReference;
 import org.apache.fop.pdf.PDFResourceContext;
 import org.apache.fop.pdf.PDFResources;
+import org.apache.fop.pdf.PDFStructElem;
+import org.apache.fop.pdf.PDFStructTreeRoot;
 import org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler;
 import org.apache.fop.render.intermediate.IFContext;
 import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
@@ -52,6 +79,70 @@
     /** logging instance */
     private static Log log = LogFactory.getLog(PDFDocumentHandler.class);
 
+    /** the following variables are used for accessibility */
+    private int pageSequenceCounter;
+    private DocumentBuilder parser = null;
+    private Document doc = null;
+    private Map structElemType = new HashMap();
+    private boolean accessEnabled = false;
+    private int parentTreeKey = -1;
+    private int pageLinkCount = 0;
+    private int mcidKey = -1;
+    private PDFParentTree parentTree = null;
+    private Map structTreeMap = new HashMap();
+    private List parentTreeList = new java.util.ArrayList();
+
+    private static class NamespaceContextImpl implements NamespaceContext {
+
+        private String uri;
+        private String prefix;
+
+        public NamespaceContextImpl() {
+        }
+
+        public NamespaceContextImpl(String prefix, String uri) {
+            this.uri = uri;
+            this.prefix = prefix;
+        }
+
+        public String getNamespaceURI(String prefix) {
+            return uri;
+        }
+
+        public void setNamespaceURI(String uri) {
+            this.uri = uri;
+        }
+
+        public String getPrefix(String uri) {
+            return prefix;
+        }
+
+        public void setPrefix(String prefix) {
+            this.prefix = prefix;
+        }
+
+        public Iterator getPrefixes(String uri) {
+            return null;
+        }
+
+    }
+
+    private static final class ParentTreeEntry {
+        private final int position;
+        private final PDFObject object;
+        private ParentTreeEntry(int p, PDFObject o) {
+            position = p;
+            object = o;
+        }
+        private int getPosition() {
+            return position;
+        }
+        private PDFObject getPDFObject() {
+            return object;
+        }
+     }
+
+
     /** the PDF Document being created */
     protected PDFDocument pdfDoc;
 
@@ -79,7 +170,7 @@
     /** Used for bookmarks/outlines. */
     protected Map pageReferences = new java.util.HashMap();
 
-    private PDFDocumentNavigationHandler documentNavigationHandler
+    private final PDFDocumentNavigationHandler documentNavigationHandler
             = new PDFDocumentNavigationHandler(this);
 
     /**
@@ -90,7 +181,7 @@
 
     /** {@inheritDoc} */
     public boolean supportsPagesOutOfOrder() {
-        return true;
+        return !accessEnabled;
     }
 
     /** {@inheritDoc} */
@@ -123,8 +214,21 @@
         super.startDocument();
         try {
             this.pdfDoc = pdfUtil.setupPDFDocument(this.outputStream);
+            this.accessEnabled = getUserAgent().accessibilityEnabled();
+            if (accessEnabled) {
+                //TODO: make document language variable, see note on wiki page PDF Accessibility
+                //TODO:                and follow-up emails on fop-dev
+                this.pdfDoc.getRoot().setLanguage("en");
+                parentTree = new PDFParentTree();
+                pageSequenceCounter = 0;
+                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+                factory.setNamespaceAware(true);
+                parser = factory.newDocumentBuilder();
+            }
         } catch (IOException e) {
             throw new IFException("I/O error in startDocument()", e);
+        } catch (ParserConfigurationException pce) {
+            throw new IFException("Error creating new DocumentBuilder", pce);
         }
     }
 
@@ -137,10 +241,34 @@
     public void endDocument() throws IFException {
         try {
             pdfDoc.getResources().addFonts(pdfDoc, fontInfo);
-            pdfDoc.outputTrailer(this.outputStream);
-
+            if (getUserAgent().accessibilityEnabled()) {
+                PDFNumsArray nums = parentTree.getNums();
+                for (int i = 0; i <= this.parentTreeKey; i++) {
+                    PDFArray tArray = new PDFArray();
+                    for (int j = 0; j < parentTreeList.size(); j++) {
+                        if (((ParentTreeEntry)parentTreeList.get(j)).getPosition() == i) {
+                            tArray.add(((ParentTreeEntry)parentTreeList.get(j)).getPDFObject());
+                        }
+                    }
+                    if (tArray.length() == 1) {
+                        nums.put(i, tArray.get(0));
+                    } else if (tArray.length() > 1) {
+                        nums.put(i, tArray);
+                    }
+                }
+                parentTree.setNums(nums);
+                getStructTreeRoot().addParentTree(parentTree);
+                pdfDoc.outputTrailer(this.outputStream);
+                parser = null;
+                doc = null;
+                structElemType = null;
+                parentTree = null;
+                structTreeMap = null;
+                parentTreeList = null;
+            } else {
+                pdfDoc.outputTrailer(this.outputStream);
+            }
             this.pdfDoc = null;
-
             pdfResources = null;
             this.generator = null;
             currentContext = null;
@@ -151,9 +279,60 @@
         super.endDocument();
     }
 
+    private PDFStructTreeRoot getStructTreeRoot() {
+        return this.pdfDoc.getRoot().getStructTreeRoot();
+    }
+
+
     /** {@inheritDoc} */
     public void startPageSequence(String id) throws IFException {
         //TODO page sequence title, country and language
+
+        if (getUserAgent().accessibilityEnabled()) {
+            try {
+                if (doc == null) {
+                    doc = parser.parse(
+                            new ByteArrayInputStream(this.getUserAgent().getReducedFOTree()));
+                }
+                PDFStructElem parent = (PDFStructElem)getStructTreeRoot().getFirstChild();
+                PDFStructElem structElemPart = new PDFStructElem("page-sequence", parent);
+                this.pdfDoc.assignObjectNumber(structElemPart);
+                this.pdfDoc.addTrailerObject(structElemPart);
+                parent.addKid(structElemPart);
+
+                String xpathExpr = "/fo:root/fo:page-sequence["
+                        + Integer.toString(++pageSequenceCounter) + "]/*";
+                XPath xpath = XPathFactory.newInstance().newXPath();
+                NamespaceContext namespaceContext = new NamespaceContextImpl("fo",
+                        "http://www.w3.org/1999/XSL/Format");
+                xpath.setNamespaceContext(namespaceContext);
+
+                NodeList nodes = (NodeList) xpath.evaluate(xpathExpr, doc,
+                        XPathConstants.NODESET);
+
+                for (int i = 0, n = nodes.getLength(); i < n; i++) {
+                    Node node = nodes.item(i);
+                    if (node.getNodeName().equals("fo:flow")
+                            || node.getNodeName().equals("fo:static-content")) {
+                        PDFStructElem structElemSect = new PDFStructElem(
+                                node.getLocalName(), structElemPart);
+                        this.pdfDoc.assignObjectNumber(structElemSect);
+                        this.pdfDoc.addTrailerObject(structElemSect);
+                        structElemPart.addKid(structElemSect);
+                        NodeList iNodes = node.getChildNodes();
+                        for (int j = 0, m = iNodes.getLength(); j < m; j++) {
+                            processContent(iNodes.item(j), structElemSect, 1);
+                        }
+                    }
+                }
+            } catch (SAXException e) {
+                throw new IFException("SAX error in startPageSequence()", e);
+            } catch (XPathExpressionException e) {
+                throw new IFException("Error while evaluating XPath expression", e);
+            } catch (IOException ioe) {
+                throw new IFException("I/O error while parsing structure tree", ioe);
+            }
+        }
     }
 
     /** {@inheritDoc} */
@@ -164,22 +343,25 @@
     /** {@inheritDoc} */
     public void startPage(int index, String name, String pageMasterName, Dimension size)
                 throws IFException {
+        // used for accessibility
+        this.parentTreeKey = this.parentTreeKey + this.pageLinkCount + 1;
+        this.mcidKey = 0;
+        this.pageLinkCount = 0;
+        //
         this.pdfResources = this.pdfDoc.getResources();
 
         this.currentPage = this.pdfDoc.getFactory().makePage(
             this.pdfResources,
             (int)Math.round(size.getWidth() / 1000),
-            (int)Math.round(size.getHeight() / 1000),
-            index);
-        //pageReferences.put(new Integer(index)/*page.getKey()*/, currentPage.referencePDF());
-        //pvReferences.put(page.getKey(), page);
-
+            (int)Math.round(size.getHeight() / 1000), index,
+            parentTreeKey);   // used for accessibility
         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, this.accessEnabled);
         // 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,
                 size.height / 1000f);
@@ -234,8 +416,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();
@@ -251,4 +433,191 @@
         }
     }
 
+    /**
+     * Used for accessibility
+     * @param position in parentTree
+     * @param o reference of PDFObject to be added to parentTree
+     */
+    void addToParentTree(int position, PDFObject o) {
+        PDFNumsArray nums = parentTree.getNums();
+        nums.put(position, o);
+        parentTree.setNums(nums);
+    }
+
+
+    /**
+     * Used for accessibility
+     * @param position in parentTree
+     * @param o object to be added to parentTree
+     */
+    void addToTempList(int position, PDFObject o) {
+        ParentTreeEntry myEntry = new ParentTreeEntry(position, o);
+        this.parentTreeList.add(myEntry);
+    }
+
+
+    /**
+     * Return the PDFObject
+     * @param ptr this is the key
+     * @return PDFObject referenced with ptr
+     */
+    PDFObject getTrailerObject(String ptr) {
+        return (PDFObject) this.structTreeMap.get(ptr);
+    }
+
+    /**
+     * Return the parent PDFObject referenced by ptr
+     * @param ptr this is the key
+     * @return PDFObject parent of PDFObject referenced with ptr
+     */
+    PDFObject getParentTrailerObject(String ptr) {
+        PDFStructElem tempStructElem = (PDFStructElem) this.structTreeMap.get(ptr);
+        return tempStructElem.getParentStructElem();
+    }
+
+    /**
+     * Adds a link object as child to StructElem
+     * @param ptr of PDFStructElem
+     * @param o PDFLink object
+     */
+    void addLinkToStructElem(String ptr, PDFObject o) {
+        PDFDictionary dict = new PDFDictionary();
+        dict.put("Type", new PDFName("OBJR"));
+        dict.put("Pg", this.currentPage);
+        dict.put("Obj", o);
+        PDFStructElem tempStructElem = (PDFStructElem) structTreeMap.get(ptr);
+        tempStructElem.addKid(dict);
+    }
+
+    /**
+     * Adds a child to StructElem, called from PDFPainter.drawImage
+     * @param ptr of PDFStructElem
+     * @param mcid sequence number within page
+     */
+    void addChildToStructElemImage(String ptr, int mcid) {
+        PDFStructElem tempStructElem = (PDFStructElem) structTreeMap.get(ptr);
+        tempStructElem.addMCIDKid(mcid);
+        tempStructElem.addPage(this.currentPage);
+        if (!tempStructElem.getLevel1()) {
+            addMeToParent(tempStructElem);
+        }
+    }
+
+    /**
+     * Adds a child to StructElem, called from PDFPainter.drawText
+     * @param ptr of PDFSturctElem
+     * @param mcid sequence number within page
+     */
+    void addChildToStructElemText(String ptr, int mcid) {
+        PDFDictionary dict = new PDFDictionary();
+        dict.put("Type", new PDFName("MCR"));
+        dict.put("Pg", this.currentPage);
+        dict.put("MCID", mcid);
+        PDFStructElem tempStructElem = (PDFStructElem) structTreeMap.get(ptr);
+        tempStructElem.addKid(dict);
+        if (!tempStructElem.getLevel1()) {
+            addMeToParent(tempStructElem);
+        }
+    }
+
+    /**
+     * Add child PDFStructElem to parent child elements
+     * Repeat until level 1 or child already exists
+     * @param childStructElem to be added
+     */
+    protected void addMeToParent(PDFStructElem childStructElem) {
+        PDFStructElem parentStructElem = (PDFStructElem) childStructElem.getParentStructElem();
+        // test if child already exists or not
+        if (parentStructElem.addUniqueKid(childStructElem)) {
+            if (!parentStructElem.getLevel1()) {
+                addMeToParent(parentStructElem);
+            }
+        }
+    }
+
+    /**
+     * increment MCID value
+     */
+    void incMCID() {
+        this.mcidKey++;
+    }
+
+    /**
+     * MCID is a sequential number per page
+     * @return MCID value
+     */
+    int getMCID() {
+        return this.mcidKey;
+    }
+
+    /**
+     * Used for accessibility
+     * @param ptr pointer into map of all structElems
+     * @return type of found structElem
+     */
+    String getStructElemType(String ptr) {
+        return (String) structElemType.get(ptr);
+    }
+
+    /**
+     * Used for accessibility
+     * @param me node being processed
+     * @param parent parent node in DOM of me
+     * @param depth depth level in DOM, static-content & flow are 0
+     */
+    private void processContent(Node me, PDFStructElem parent, int depth) {
+        String ptr;
+        Node attr = me.getAttributes().getNamedItem("foi:ptr");
+        if (attr != null) {
+            ptr = attr.getNodeValue();
+        } else {
+            log.error("Accessibility: missing foi:ptr");
+            ptr = "";
+        }
+        String s = me.getLocalName();
+        PDFStructElem structElem = new PDFStructElem(s, parent);
+        this.pdfDoc.assignObjectNumber(structElem);
+        this.pdfDoc.addTrailerObject(structElem);
+        if (depth == 1) {
+            parent.addKid(structElem);
+            structElem.setLevel1();
+        }
+        if (s.equals("external-graphic") || s.equals("instream-foreign-object")) {
+            Node altTextNode = me.getAttributes().getNamedItem("fox:alt-text");
+            if (altTextNode != null) {
+                structElem.put("Alt", altTextNode.getNodeValue());
+            } else {
+                log.warn("fo:" + s
+                 + " requires an alternative text attribute fox:alt-text for accessibility");
+                structElem.put("Alt", "No alternate text specified");
+            }
+        }
+        // the following map is used e.g. in PDFPainter.drawText
+        structElemType.put(ptr, structElem.get("S").toString());
+        // this map will be used for fast access of the StructElem by ptr
+        structTreeMap.put(ptr, structElem);
+        NodeList nodes = me.getChildNodes();
+        depth++;
+        for (int i = 0, n = nodes.getLength(); i < n; i++) {
+            processContent(nodes.item(i), structElem, depth);
+        }
+    }
+
+    /**
+     * used for accessibility
+     * @return mcid to be used for next link to be processed
+     */
+    int getPageLinkCountPlusPageParentKey() {
+        this.pageLinkCount++;
+        return (this.parentTreeKey + this.pageLinkCount);
+    }
+
+    /**
+     * used for accessibility
+     * @return current parentTreeKey
+     */
+    int getCurrentParentTreeKey() {
+        return this.parentTreeKey;
+    }
+
 }

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java Thu Feb 19 18:04:18 2009
@@ -42,15 +42,18 @@
 import org.apache.fop.render.intermediate.extensions.URIAction;
 import org.apache.fop.render.pdf.PDFDocumentHandler.PageReference;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
 /**
  * Implementation of the {@link IFDocumentNavigationHandler} interface for PDF output.
  */
 public class PDFDocumentNavigationHandler implements IFDocumentNavigationHandler {
+    private static Log log = LogFactory.getLog(PDFDocumentHandler.class);
+    private final PDFDocumentHandler documentHandler;
 
-    private 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 +114,14 @@
         PDFLink pdfLink = getPDFDoc().getFactory().makeLink(
                 targetRect2D, pdfAction);
         if (pdfLink != null) {
+          //accessibility: ptr has a value
+            String ptr = link.getAction().getPtr();
+            if (ptr.length() > 0) {
+                this.documentHandler.addLinkToStructElem(ptr, pdfLink);
+                int id = this.documentHandler.getPageLinkCountPlusPageParentKey();
+                pdfLink.setStructParent(id);
+                this.documentHandler.addToParentTree(id, pdfLink );
+            }
             documentHandler.currentPage.addAnnotation(pdfLink);
         }
     }

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawJPEG.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawJPEG.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawJPEG.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawJPEG.java Thu Feb 19 18:04:18 2009
@@ -82,7 +82,17 @@
         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().accessibilityEnabled()) {
+            String structElemType = pdfContext.getStructElemType();
+            if (structElemType.length() > 0) {
+                int sequenceNum = pdfContext.getSequenceNum();
+                generator.placeImage(x, y, w, h, xobj, structElemType, sequenceNum);
+            } else {
+                generator.placeImage(x, y, w, h, xobj);
+            }
+        } else {
+            generator.placeImage(x, y, w, h, xobj);
+        }
     }
 
     /** {@inheritDoc} */

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFImageHandlerRenderedImage.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFImageHandlerRenderedImage.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFImageHandlerRenderedImage.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFImageHandlerRenderedImage.java Thu Feb 19 18:04:18 2009
@@ -83,7 +83,13 @@
         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().accessibilityEnabled()) {
+            String structElemType = pdfContext.getStructElemType();
+            int sequenceNum = pdfContext.getSequenceNum();
+            generator.placeImage(x, y, w, h, xobj, structElemType, sequenceNum);
+        } else {
+            generator.placeImage(x, y, w, h, xobj);
+        }
     }
 
     /** {@inheritDoc} */

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java Thu Feb 19 18:04:18 2009
@@ -101,8 +101,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 +121,11 @@
          */
         generator.comment("SVG setup");
         generator.saveGraphicsState();
+        if (context.getUserAgent().accessibilityEnabled()) {
+            String structElemType = pdfContext.getStructElemType();
+            int sequenceNum = pdfContext.getSequenceNum();
+            generator.startAccessSequence(structElemType, sequenceNum);
+        }
         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().accessibilityEnabled()) {
+            generator.restoreGraphicsStateAccess();
+        } else {
+            generator.restoreGraphicsState();
+        }
         generator.comment("SVG end");
     }
 

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFPainter.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFPainter.java Thu Feb 19 18:04:18 2009
@@ -59,12 +59,18 @@
     /** logging instance */
     private static Log log = LogFactory.getLog(PDFPainter.class);
 
-    private PDFDocumentHandler documentHandler;
+    private final PDFDocumentHandler documentHandler;
 
     /** The current content generator */
     protected PDFContentGenerator generator;
 
-    private PDFBorderPainter borderPainter;
+    private final PDFBorderPainter borderPainter;
+
+    private boolean accessEnabled = false;
+
+    private int mcid; // used for accessibility
+
+    private String structElemType; // used for accessibility
 
     /**
      * Default constructor.
@@ -76,6 +82,7 @@
         this.generator = documentHandler.generator;
         this.borderPainter = new PDFBorderPainter(this.generator);
         this.state = IFState.create();
+        accessEnabled = this.getUserAgent().accessibilityEnabled();
     }
 
     /** {@inheritDoc} */
@@ -122,15 +129,50 @@
     }
 
     /** {@inheritDoc} */
-    public void drawImage(String uri, Rectangle rect) throws IFException {
+    public void drawImage(String uri, Rectangle rect, String ptr)
+            throws IFException {
         PDFXObject xobject = getPDFDoc().getXObject(uri);
         if (xobject != null) {
-            placeImage(rect, xobject);
+            if (accessEnabled && ptr.length() > 0) {
+                mcid = this.documentHandler.getMCID();
+                mcid++;                          // fix for Acro Checker
+                this.documentHandler.incMCID();  // simulating a parent text element
+                structElemType = this.documentHandler.getStructElemType(ptr);
+                this.documentHandler.addToTempList(
+                        this.documentHandler.getCurrentParentTreeKey(),
+                        this.documentHandler.getParentTrailerObject(ptr));
+                this.documentHandler.addToTempList(
+                        this.documentHandler.getCurrentParentTreeKey(),
+                        this.documentHandler.getTrailerObject(ptr));
+                placeImageAccess(rect, xobject);
+                this.documentHandler.addChildToStructElemImage(ptr, mcid);
+                this.documentHandler.incMCID();
+            } else {
+                placeImage(rect, xobject);
+            }
             return;
         }
-
-        drawImageUsingURI(uri, rect);
-
+        if (accessEnabled && ptr.length() > 0) {
+            mcid = this.documentHandler.getMCID();
+            mcid++;                          // fix for Acro Checker
+            this.documentHandler.incMCID();  // simulating a parent text element
+            structElemType = this.documentHandler.getStructElemType(ptr);
+            this.documentHandler.addToTempList(
+                    this.documentHandler.getCurrentParentTreeKey(),
+                    this.documentHandler.getParentTrailerObject(ptr));
+            this.documentHandler.addToTempList(
+                    this.documentHandler.getCurrentParentTreeKey(),
+                    this.documentHandler.getTrailerObject(ptr));
+            //PDFRenderingContext pdfContext = new PDFRenderingContext(
+            //        getUserAgent(), generator, this.documentHandler.currentPage, getFontInfo());
+            //pdfContext.setMCID(mcid);
+            //pdfContext.setStructElemType(structElemType);
+            drawImageUsingURI(uri, rect);
+            this.documentHandler.addChildToStructElemImage(ptr, mcid);
+            this.documentHandler.incMCID();
+        } else {
+            drawImageUsingURI(uri, rect);
+        }
         flushPDFDoc();
     }
 
@@ -138,6 +180,8 @@
     protected RenderingContext createRenderingContext() {
         PDFRenderingContext pdfContext = new PDFRenderingContext(
                 getUserAgent(), generator, this.documentHandler.currentPage, getFontInfo());
+        pdfContext.setMCID(mcid);
+        pdfContext.setStructElemType(structElemType);
         return pdfContext;
     }
 
@@ -158,11 +202,43 @@
                           + " 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(structElemType, 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 {
-        drawImageUsingDocument(doc, rect);
-
+    public void drawImage(Document doc, Rectangle rect, String ptr) throws IFException {
+        if (accessEnabled && ptr.length() > 0) {
+            mcid = this.documentHandler.getMCID();
+            mcid++;                          // fix for Acro Checker
+            this.documentHandler.incMCID();  // simulating a parent text element
+            structElemType = this.documentHandler.getStructElemType(ptr);
+            this.documentHandler.addToTempList(
+                    this.documentHandler.getCurrentParentTreeKey(),
+                    this.documentHandler.getParentTrailerObject(ptr));
+            this.documentHandler.addToTempList(
+                    this.documentHandler.getCurrentParentTreeKey(),
+                    this.documentHandler.getTrailerObject(ptr));
+            drawImageUsingDocument(doc, rect);
+            this.documentHandler.addChildToStructElemImage(ptr, mcid);
+            this.documentHandler.incMCID();
+        } else {
+            drawImageUsingDocument(doc, rect);
+        }
         flushPDFDoc();
     }
 
@@ -253,10 +329,38 @@
     }
 
     /** {@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, String ptr)
             throws IFException {
-        generator.updateColor(state.getTextColor(), true, null);
-        generator.beginTextObject();
+        if (accessEnabled ) {
+            int mcId;
+            String structElType = "";
+            if (ptr != null && ptr.length() > 0) {
+                mcId = this.documentHandler.getMCID();
+                this.documentHandler.addToTempList(
+                        this.documentHandler.getCurrentParentTreeKey(),
+                        this.documentHandler.getTrailerObject(ptr));
+                structElType = this.documentHandler.getStructElemType(ptr);
+                if (generator.getTextUtil().isInTextObject()) {
+                    generator.separateTextElements(mcId, structElType);
+                }
+                generator.updateColor(state.getTextColor(), true, null);
+                generator.beginTextObjectAccess(mcId, structElType);
+                this.documentHandler.addChildToStructElemText(ptr, mcId);
+                this.documentHandler.incMCID();
+            } else {
+                // <fo:leader leader-pattern="use-content">
+                if (generator.getTextUtil().isInTextObject()) {
+                    generator.separateTextElementFromLeader();
+                }
+                generator.updateColor(state.getTextColor(), true, null);
+                generator.beginLeaderTextObject();
+            }
+        } 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 +381,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();

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFRenderer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFRenderer.java?rev=745949&r1=745948&r2=745949&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFRenderer.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/render/pdf/PDFRenderer.java Thu Feb 19 18:04:18 2009
@@ -461,7 +461,8 @@
         double h = bounds.getHeight();
         pageHeight = (int) h;
 
-        this.generator = new PDFContentGenerator(this.pdfDoc, this.ostream, this.currentPage);
+        this.generator = new PDFContentGenerator(this.pdfDoc, this.ostream, this.currentPage,
+                false);
         this.borderPainter = new PDFBorderPainter(this.generator);
 
         // Transform the PDF's default coordinate system (0,0 at lower left) to the PDFRenderer's
@@ -1073,7 +1074,7 @@
     }
 
     /** {@inheritDoc} */
-    protected void drawImage(String url, Rectangle2D pos, Map foreignAttributes) {
+    protected void drawImage(String url, Rectangle2D pos, Map foreignAttributes, String ptr) {
         endTextObject();
         putImage(url, pos, foreignAttributes);
     }



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org