Author: ssteiner
Date: Tue Jun 16 11:46:50 2015
New Revision: 1685770

URL: http://svn.apache.org/r1685770
Log:
FOP-2488: Support PDF/UA

Added:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFUAMode.java   (with 
props)
    xmlgraphics/fop/trunk/test/java/org/apache/fop/pdf/PDFUATestCase.java   
(with props)
Modified:
    xmlgraphics/fop/trunk/lib/xmlgraphics-commons-svn-trunk.jar
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FOUserAgent.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/BasicLink.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFMetadata.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFProfile.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFRoot.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFStructElem.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFPainter.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOption.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java
    xmlgraphics/fop/trunk/test/java/org/apache/fop/fo/complete_document.fo

Modified: xmlgraphics/fop/trunk/lib/xmlgraphics-commons-svn-trunk.jar
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/lib/xmlgraphics-commons-svn-trunk.jar?rev=1685770&r1=1685769&r2=1685770&view=diff
==============================================================================
Binary files - no diff available.

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java?rev=1685770&r1=1685769&r2=1685770&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java
 Tue Jun 16 11:46:50 2015
@@ -33,9 +33,9 @@ import org.apache.fop.accessibility.Stru
 import org.apache.fop.fo.FOEventHandler;
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.FOText;
+import org.apache.fop.fo.FObj;
 import org.apache.fop.fo.extensions.ExtensionElementMapping;
 import org.apache.fop.fo.extensions.InternalElementMapping;
-import org.apache.fop.fo.flow.AbstractGraphics;
 import org.apache.fop.fo.flow.AbstractRetrieveMarker;
 import org.apache.fop.fo.flow.BasicLink;
 import org.apache.fop.fo.flow.Block;
@@ -384,7 +384,7 @@ class StructureTreeEventTrigger extends
 
     @Override
     public void startLink(BasicLink basicLink) {
-        startElementWithID(basicLink);
+        startElementWithIDAndAltText(basicLink, basicLink.getAltText());
     }
 
     @Override
@@ -394,13 +394,13 @@ class StructureTreeEventTrigger extends
 
     @Override
     public void image(ExternalGraphic eg) {
-        startElementWithIDAndAltText(eg);
+        startElementWithIDAndAltText(eg, eg.getAltText());
         endElement(eg);
     }
 
     @Override
     public void startInstreamForeignObject(InstreamForeignObject ifo) {
-        startElementWithIDAndAltText(ifo);
+        startElementWithIDAndAltText(ifo, ifo.getAltText());
     }
 
     @Override
@@ -523,12 +523,12 @@ class StructureTreeEventTrigger extends
                         node.getParent().getStructureTreeElement()));
     }
 
-    private void startElementWithIDAndAltText(AbstractGraphics node) {
+    private void startElementWithIDAndAltText(FObj node, String altText) {
         AttributesImpl attributes = new AttributesImpl();
         String localName = node.getLocalName();
-        addRole(node, attributes);
+        addRole((CommonAccessibilityHolder)node, attributes);
         addAttribute(attributes, ExtensionElementMapping.URI, "alt-text",
-                ExtensionElementMapping.STANDARD_PREFIX, node.getAltText());
+                ExtensionElementMapping.STANDARD_PREFIX, altText);
         node.setStructureTreeElement(
                 structureTreeEventHandler.startImageNode(localName, attributes,
                         node.getParent().getStructureTreeElement()));

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FOUserAgent.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FOUserAgent.java?rev=1685770&r1=1685769&r2=1685770&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FOUserAgent.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/apps/FOUserAgent.java Tue Jun 
16 11:46:50 2015
@@ -106,6 +106,7 @@ public class FOUserAgent {
     private EventBroadcaster eventBroadcaster = new FOPEventBroadcaster();
     private StructureTreeEventHandler structureTreeEventHandler
             = DummyStructureTreeEventHandler.INSTANCE;
+    private boolean pdfUAEnabled;
 
     /** Producer:  Metadata element for the system/software that produces
      * the document. (Some renderers can store this in the document.)
@@ -580,6 +581,14 @@ public class FOUserAgent {
         return this.eventBroadcaster;
     }
 
+    public boolean isPdfUAEnabled() {
+        return pdfUAEnabled;
+    }
+
+    public void setPdfUAEnabled(boolean pdfUAEnabled) {
+        this.pdfUAEnabled = pdfUAEnabled;
+    }
+
     private class FOPEventBroadcaster extends DefaultEventBroadcaster {
 
         private EventListener rootListener;

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/BasicLink.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/BasicLink.java?rev=1685770&r1=1685769&r2=1685770&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/BasicLink.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/BasicLink.java Tue 
Jun 16 11:46:50 2015
@@ -50,6 +50,7 @@ public class BasicLink extends InlineLev
     // private ToBeImplementedProperty indicateDestination;
     private String internalDestination;
     private int showDestination;
+    private String altText;
     // private ToBeImplementedProperty targetProcessingContext;
     // private ToBeImplementedProperty targetPresentationContext;
     // private ToBeImplementedProperty targetStylesheet;
@@ -93,6 +94,12 @@ public class BasicLink extends InlineLev
             // slightly stronger than spec "should be specified"
             getFOValidationEventProducer().missingLinkDestination(this, 
getName(), locator);
         }
+        if (getUserAgent().isAccessibilityEnabled()) {
+            altText = pList.get(PR_X_ALT_TEXT).getString();
+            if (altText.equals("") && getUserAgent().isPdfUAEnabled()) {
+                getFOValidationEventProducer().altTextMissing(this, 
getLocalName(), getLocator());
+            }
+        }
     }
 
     /** {@inheritDoc} */
@@ -212,4 +219,8 @@ public class BasicLink extends InlineLev
     public int getNameId() {
         return FO_BASIC_LINK;
     }
+
+    public String getAltText() {
+        return altText;
+    }
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFMetadata.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFMetadata.java?rev=1685770&r1=1685769&r2=1685770&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFMetadata.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFMetadata.java Tue Jun 
16 11:46:50 2015
@@ -38,6 +38,8 @@ import org.apache.xmlgraphics.xmp.schema
 import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFSchema;
 import org.apache.xmlgraphics.xmp.schemas.pdf.PDFAAdapter;
 import org.apache.xmlgraphics.xmp.schemas.pdf.PDFAXMPSchema;
+import org.apache.xmlgraphics.xmp.schemas.pdf.PDFUAAdapter;
+import org.apache.xmlgraphics.xmp.schemas.pdf.PDFUAXMPSchema;
 import org.apache.xmlgraphics.xmp.schemas.pdf.PDFVTAdapter;
 import org.apache.xmlgraphics.xmp.schemas.pdf.PDFVTXMPSchema;
 import org.apache.xmlgraphics.xmp.schemas.pdf.PDFXAdapter;
@@ -161,6 +163,12 @@ public class PDFMetadata extends PDFStre
         //Somewhat redundant but some PDF/A checkers issue a warning without 
this.
         dc.setFormat("application/pdf");
 
+        PDFUAMode pdfuaMode = pdfDoc.getProfile().getPDFUAMode();
+        if (pdfuaMode.isEnabled()) {
+            PDFUAAdapter pdfua = PDFUAXMPSchema.getAdapter(meta);
+            pdfua.setPart(pdfuaMode.getPart());
+        }
+
         //PDF/A identification
         PDFAMode pdfaMode = pdfDoc.getProfile().getPDFAMode();
         if (pdfaMode.isEnabled()) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFProfile.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFProfile.java?rev=1685770&r1=1685769&r2=1685770&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFProfile.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFProfile.java Tue Jun 
16 11:46:50 2015
@@ -37,6 +37,8 @@ public class PDFProfile {
      */
     protected PDFAMode pdfAMode = PDFAMode.DISABLED;
 
+    protected PDFUAMode pdfUAMode = PDFUAMode.DISABLED;
+
     /**
      * Indicates the PDF/X mode currently active. Defaults to "no 
restrictions", i.e.
      * PDF/X not active.
@@ -82,6 +84,10 @@ public class PDFProfile {
         return this.pdfAMode;
     }
 
+    public PDFUAMode getPDFUAMode() {
+        return this.pdfUAMode;
+    }
+
     /** @return true if any PDF/A mode is active */
     public boolean isPDFAActive() {
         return getPDFAMode() != PDFAMode.DISABLED;
@@ -99,6 +105,14 @@ public class PDFProfile {
         validateProfileCombination();
     }
 
+    public void setPDFUAMode(PDFUAMode mode) {
+        if (mode == null) {
+            mode = PDFUAMode.DISABLED;
+        }
+        this.pdfUAMode = mode;
+        validateProfileCombination();
+    }
+
     /** @return the PDF/X mode */
     public PDFXMode getPDFXMode() {
         return this.pdfXMode;
@@ -150,6 +164,8 @@ public class PDFProfile {
             sb.append(getPDFAMode());
         } else if (isPDFXActive()) {
             sb.append(getPDFXMode());
+        } else if (getPDFUAMode().isEnabled()) {
+            sb.append(getPDFUAMode());
         } else {
             sb.append(super.toString());
         }
@@ -234,25 +250,28 @@ public class PDFProfile {
      * Checks a few things required for tagged PDF.
      */
     public void verifyTaggedPDF() {
-        if (getPDFAMode().isLevelA()) {
+        if (getPDFAMode().isLevelA() || getPDFUAMode().isEnabled()) {
             final String err = "{0} requires the {1} dictionary entry to be 
set";
+            String mode = getPDFAMode().toString();
+            if (getPDFUAMode().isEnabled()) {
+                mode = getPDFUAMode().toString();
+            }
             PDFDictionary markInfo = getDocument().getRoot().getMarkInfo();
             if (markInfo == null) {
                 throw new PDFConformanceException(format(
-                        "{0} requires that the accessibility option in the 
configuration file be enabled",
-                        getPDFAMode()));
+                        "{0} requires that the accessibility option in the 
configuration file be enabled", mode));
             }
             if (!Boolean.TRUE.equals(markInfo.get("Marked"))) {
                 throw new PDFConformanceException(format(err,
-                        new Object[] {getPDFAMode(), "Marked"}));
+                        new Object[] {mode, "Marked"}));
             }
             if (getDocument().getRoot().getStructTreeRoot() == null) {
                 throw new PDFConformanceException(format(err,
-                        new Object[] {getPDFAMode(), "StructTreeRoot"}));
+                        new Object[] {mode, "StructTreeRoot"}));
             }
             if (getDocument().getRoot().getLanguage() == null) {
                 throw new PDFConformanceException(format(err,
-                        new Object[] {getPDFAMode(), "Lang"}));
+                        new Object[] {mode, "Lang"}));
             }
         }
     }
@@ -264,13 +283,16 @@ public class PDFProfile {
 
     /** @return true if all fonts need to be embedded. */
     public boolean isFontEmbeddingRequired() {
-        return isPDFAActive() || isPDFXActive();
+        return isPDFAActive() || isPDFXActive() || getPDFUAMode().isEnabled();
     }
 
     /** Checks if a title may be absent. */
     public void verifyTitleAbsent() {
+        final String err = "{0} requires the title to be set.";
+        if (getPDFUAMode().isEnabled()) {
+            throw new PDFConformanceException(format(err, getPDFUAMode()));
+        }
         if (isPDFXActive()) {
-            final String err = "{0} requires the title to be set.";
             throw new PDFConformanceException(format(err, getPDFXMode()));
         }
     }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFRoot.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFRoot.java?rev=1685770&r1=1685769&r2=1685770&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFRoot.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFRoot.java Tue Jun 16 
11:46:50 2015
@@ -82,6 +82,11 @@ public class PDFRoot extends PDFDictiona
 
     /** {@inheritDoc} */
     public int output(OutputStream stream) throws IOException {
+        if (document.getProfile().getPDFUAMode().isEnabled()) {
+            PDFDictionary d = new PDFDictionary();
+            d.put("DisplayDocTitle", true);
+            put("ViewerPreferences", d);
+        }
         getDocument().getProfile().verifyTaggedPDF();
         return super.output(stream);
     }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFStructElem.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFStructElem.java?rev=1685770&r1=1685769&r2=1685770&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFStructElem.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFStructElem.java Tue 
Jun 16 11:46:50 2015
@@ -243,6 +243,14 @@ public class PDFStructElem extends Struc
         return this.kids;
     }
 
+    public int output(OutputStream stream) throws IOException {
+        if (getDocument().getProfile().getPDFUAMode().isEnabled()
+                && entries.containsKey("Alt") && "".equals(get("Alt"))) {
+            put("Alt", "No alternate text specified");
+        }
+        return super.output(stream);
+    }
+
     /**
      * Class representing a placeholder for a PDF Structure Element.
      */

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFUAMode.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFUAMode.java?rev=1685770&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFUAMode.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFUAMode.java Tue Jun 16 
11:46:50 2015
@@ -0,0 +1,85 @@
+/*
+ * 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;
+
+/** Enum class for PDF/UA modes. */
+public enum PDFUAMode {
+
+    /** PDF/UA disabled. */
+    DISABLED("PDF/UA disabled"),
+    /** PDF/UA-1 enabled. */
+    PDFUA_1(1);
+
+    private final String name;
+
+    private final int part;
+
+    /**
+     * Constructor to add a new named item.
+     * @param name Name of the item.
+     */
+    private PDFUAMode(String name) {
+        this.name = name;
+        this.part = 0;
+    }
+
+    private PDFUAMode(int part) {
+        this.name = "PDF/UA-" + part;
+        this.part = part;
+    }
+
+    /** @return the name of the enum */
+    public String getName() {
+        return this.name;
+    }
+
+    public int getPart() {
+        return part;
+    }
+
+    /**
+     * Returns {@code true} if this enum corresponds to one of the available 
PDF/A modes.
+     *
+     * @return {@code true} if this is not DISABLED
+     */
+    public boolean isEnabled() {
+        return this != DISABLED;
+    }
+
+    /**
+     * Returns the mode enum object given a String.
+     * @param s the string
+     * @return the PDFAMode enum object (DISABLED will be returned if no match 
is found)
+     */
+    public static PDFUAMode getValueOf(String s) {
+        for (PDFUAMode mode : values()) {
+            if (mode.name.equalsIgnoreCase(s)) {
+                return mode;
+            }
+        }
+        return DISABLED;
+    }
+
+    /** {@inheritDoc} */
+    public String toString() {
+        return name;
+    }
+
+}

Propchange: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/PDFUAMode.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFPainter.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFPainter.java?rev=1685770&r1=1685769&r2=1685770&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFPainter.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFPainter.java 
Tue Jun 16 11:46:50 2015
@@ -44,6 +44,9 @@ import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.fonts.LazyFont;
 import org.apache.fop.fonts.SingleByteFont;
 import org.apache.fop.fonts.Typeface;
+import org.apache.fop.pdf.PDFArray;
+import org.apache.fop.pdf.PDFDictionary;
+import org.apache.fop.pdf.PDFName;
 import org.apache.fop.pdf.PDFNumber;
 import org.apache.fop.pdf.PDFStructElem;
 import org.apache.fop.pdf.PDFTextUtil;
@@ -173,6 +176,7 @@ public class PDFPainter extends Abstract
                 placeImage(rect, xobject);
             }
         } else {
+            addStructTreeBBox(rect);
             drawImageUsingURI(uri, rect);
             if 
(!getDocumentHandler().getPDFDocument().isLinearizationEnabled()) {
                 flushPDFDoc();
@@ -180,6 +184,20 @@ public class PDFPainter extends Abstract
         }
     }
 
+    private void addStructTreeBBox(Rectangle rect) {
+        if (accessEnabled && 
getDocumentHandler().getPDFDocument().getProfile().getPDFUAMode().isEnabled()) {
+            PDFStructElem structElem = (PDFStructElem) 
getContext().getStructureTreeElement();
+            PDFDictionary d = new PDFDictionary();
+            int x = rect.x / 1000;
+            int y = rect.y / 1000;
+            int w = rect.width / 1000;
+            int h = rect.height / 1000;
+            d.put("BBox", new PDFArray(x, y, w, h));
+            d.put("O", new PDFName("Layout"));
+            structElem.put("A", d);
+        }
+    }
+
     @Override
     protected void drawImageUsingURI(String uri, Rectangle rect) {
         ImageManager manager = getUserAgent().getImageManager();
@@ -263,6 +281,7 @@ public class PDFPainter extends Abstract
         if (accessEnabled) {
             PDFStructElem structElem = (PDFStructElem) 
getContext().getStructureTreeElement();
             prepareImageMCID(structElem);
+            addStructTreeBBox(rect);
         }
         drawImageUsingDocument(doc, rect);
         if (!getDocumentHandler().getPDFDocument().isLinearizationEnabled()) {
@@ -315,6 +334,9 @@ public class PDFPainter extends Abstract
         }
         if (rect.width != 0 && rect.height != 0) {
             generator.endTextObject();
+            if (accessEnabled && getUserAgent().isPdfUAEnabled()) {
+                generator.beginMarkedContentSequence(null, 0, null);
+            }
             if (fill != null) {
                 if (fill instanceof Color) {
                     generator.updateColor((Color)fill, true, null);
@@ -336,6 +358,9 @@ public class PDFPainter extends Abstract
             }*/
             sb.append('\n');
             generator.add(sb.toString());
+            if (accessEnabled && getUserAgent().isPdfUAEnabled()) {
+                generator.endMarkedContentSequence();
+            }
         }
     }
 
@@ -345,23 +370,32 @@ public class PDFPainter extends Abstract
             BorderProps left, BorderProps right, Color innerBackgroundColor) 
throws IFException {
         if (top != null || bottom != null || left != null || right != null) {
             generator.endTextObject();
+            if (accessEnabled && getUserAgent().isPdfUAEnabled()) {
+                generator.beginMarkedContentSequence(null, 0, null);
+            }
             this.borderPainter.drawBorders(rect, top, bottom, left, right, 
innerBackgroundColor);
+            if (accessEnabled && getUserAgent().isPdfUAEnabled()) {
+                generator.endMarkedContentSequence();
+            }
         }
     }
 
-
-
-
     /** {@inheritDoc} */
     @Override
     public void drawLine(Point start, Point end, int width, Color color, 
RuleStyle style)
         throws IFException {
         generator.endTextObject();
+        if (accessEnabled && getUserAgent().isPdfUAEnabled()) {
+            generator.beginMarkedContentSequence(null, 0, null);
+        }
         try {
             this.graphicsPainter.drawLine(start, end, width, color, style);
         } catch (IOException ioe) {
             throw new IFException("Cannot draw line", ioe);
         }
+        if (accessEnabled && getUserAgent().isPdfUAEnabled()) {
+            generator.endMarkedContentSequence();
+        }
     }
 
     private Typeface getTypeface(String fontName) {

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java?rev=1685770&r1=1685769&r2=1685770&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java 
(original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java 
Tue Jun 16 11:46:50 2015
@@ -60,6 +60,7 @@ import static org.apache.fop.render.pdf.
 import static org.apache.fop.render.pdf.PDFRendererOption.MERGE_FONTS;
 import static org.apache.fop.render.pdf.PDFRendererOption.OUTPUT_PROFILE;
 import static org.apache.fop.render.pdf.PDFRendererOption.PDF_A_MODE;
+import static org.apache.fop.render.pdf.PDFRendererOption.PDF_UA_MODE;
 import static org.apache.fop.render.pdf.PDFRendererOption.PDF_VT_MODE;
 import static org.apache.fop.render.pdf.PDFRendererOption.PDF_X_MODE;
 import static org.apache.fop.render.pdf.PDFRendererOption.VERSION;
@@ -134,6 +135,7 @@ public final class PDFRendererConfig imp
             try {
                 buildFilterMapFromConfiguration(cfg);
                 parseAndPut(PDF_A_MODE, cfg);
+                parseAndPut(PDF_UA_MODE, cfg);
                 parseAndPut(PDF_X_MODE, cfg);
                 parseAndPut(PDF_VT_MODE, cfg);
                 configureEncryptionParams(cfg, userAgent, strict);

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOption.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOption.java?rev=1685770&r1=1685769&r2=1685770&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOption.java 
(original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOption.java 
Tue Jun 16 11:46:50 2015
@@ -24,6 +24,7 @@ import java.net.URISyntaxException;
 
 import org.apache.fop.apps.io.InternalResourceResolver;
 import org.apache.fop.pdf.PDFAMode;
+import org.apache.fop.pdf.PDFUAMode;
 import org.apache.fop.pdf.PDFVTMode;
 import org.apache.fop.pdf.PDFXMode;
 import org.apache.fop.pdf.Version;
@@ -43,6 +44,12 @@ public enum PDFRendererOption implements
             return PDFAMode.getValueOf(value);
         }
     },
+    PDF_UA_MODE("pdf-ua-mode", PDFUAMode.DISABLED) {
+        @Override
+        PDFUAMode deserialize(String value) {
+            return PDFUAMode.getValueOf(value);
+        }
+    },
     /** Rendering Options key for the PDF/X mode, default: {@link 
PDFXMode#DISABLED} */
     PDF_X_MODE("pdf-x-mode", PDFXMode.DISABLED) {
         @Override

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java?rev=1685770&r1=1685769&r2=1685770&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java
 Tue Jun 16 11:46:50 2015
@@ -26,6 +26,7 @@ import java.util.Map;
 
 import org.apache.fop.pdf.PDFAMode;
 import org.apache.fop.pdf.PDFEncryptionParams;
+import org.apache.fop.pdf.PDFUAMode;
 import org.apache.fop.pdf.PDFVTMode;
 import org.apache.fop.pdf.PDFXMode;
 import org.apache.fop.pdf.Version;
@@ -36,6 +37,7 @@ import static org.apache.fop.render.pdf.
 import static org.apache.fop.render.pdf.PDFRendererOption.MERGE_FONTS;
 import static org.apache.fop.render.pdf.PDFRendererOption.OUTPUT_PROFILE;
 import static org.apache.fop.render.pdf.PDFRendererOption.PDF_A_MODE;
+import static org.apache.fop.render.pdf.PDFRendererOption.PDF_UA_MODE;
 import static org.apache.fop.render.pdf.PDFRendererOption.PDF_VT_MODE;
 import static org.apache.fop.render.pdf.PDFRendererOption.PDF_X_MODE;
 import static org.apache.fop.render.pdf.PDFRendererOption.VERSION;
@@ -105,6 +107,10 @@ public final class PDFRendererOptionsCon
         return (PDFAMode) properties.get(PDF_A_MODE);
     }
 
+    public PDFUAMode getPDFUAMode() {
+        return (PDFUAMode) properties.get(PDF_UA_MODE);
+    }
+
     public PDFXMode getPDFXMode() {
         return (PDFXMode) properties.get(PDF_X_MODE);
     }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java?rev=1685770&r1=1685769&r2=1685770&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java 
(original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java 
Tue Jun 16 11:46:50 2015
@@ -164,6 +164,8 @@ class PDFRenderingUtil {
 
     private void updatePDFProfiles() {
         pdfDoc.getProfile().setPDFAMode(rendererConfig.getPDFAMode());
+        pdfDoc.getProfile().setPDFUAMode(rendererConfig.getPDFUAMode());
+        
userAgent.setPdfUAEnabled(pdfDoc.getProfile().getPDFUAMode().isEnabled());
         pdfDoc.getProfile().setPDFXMode(rendererConfig.getPDFXMode());
         pdfDoc.getProfile().setPDFVTMode(rendererConfig.getPDFVTMode());
     }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java?rev=1685770&r1=1685769&r2=1685770&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java
 Tue Jun 16 11:46:50 2015
@@ -91,7 +91,7 @@ public class PDFStructureTreeBuilder imp
         addBuilder("list-item-body",            
StandardStructureTypes.List.LBODY);
         addBuilder("list-item-label",           
StandardStructureTypes.List.LBL);
         // Dynamic Effects: Link and Multi Formatting Objects
-        addBuilder("basic-link",                
StandardStructureTypes.InlineLevelStructure.LINK);
+        addBuilder("basic-link",                new LinkBuilder());
         // Out-of-Line Formatting Objects
         addBuilder("float",                     
StandardStructureTypes.Grouping.DIV);
         addBuilder("footnote",                  
StandardStructureTypes.InlineLevelStructure.NOTE);
@@ -247,6 +247,22 @@ public class PDFStructureTreeBuilder imp
 
     }
 
+    private static class LinkBuilder extends DefaultStructureElementBuilder {
+        LinkBuilder() {
+            super(StandardStructureTypes.InlineLevelStructure.LINK);
+        }
+
+        @Override
+        protected void setAttributes(PDFStructElem structElem, Attributes 
attributes) {
+            super.setAttributes(structElem, attributes);
+            String altTextNode = 
attributes.getValue(ExtensionElementMapping.URI, "alt-text");
+            if (altTextNode == null) {
+                altTextNode = "No alternate text specified";
+            }
+            structElem.put("Alt", altTextNode);
+        }
+    }
+
     private static class TableBuilder extends DefaultStructureElementBuilder {
 
         TableBuilder() {
@@ -391,7 +407,8 @@ public class PDFStructureTreeBuilder imp
     }
 
     private boolean isPDFA1Safe(String name) {
-        return !(pdfFactory.getDocument().getProfile().getPDFAMode().isPart1()
+        return !((pdfFactory.getDocument().getProfile().getPDFAMode().isPart1()
+                || 
pdfFactory.getDocument().getProfile().getPDFUAMode().isEnabled())
                 && (name.equals("table-body")
                 || name.equals("table-header")
                 || name.equals("table-footer")));

Modified: xmlgraphics/fop/trunk/test/java/org/apache/fop/fo/complete_document.fo
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/fo/complete_document.fo?rev=1685770&r1=1685769&r2=1685770&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/test/java/org/apache/fop/fo/complete_document.fo 
(original)
+++ xmlgraphics/fop/trunk/test/java/org/apache/fop/fo/complete_document.fo Tue 
Jun 16 11:46:50 2015
@@ -38,7 +38,7 @@
     </fo:static-content>
     <fo:flow flow-name="xsl-region-body">
       <fo:block id="4">This is a link to the <fo:wrapper id="5" 
color="blue"><fo:basic-link id="6" 
-            internal-destination="second-start">next 
page-sequence</fo:basic-link></fo:wrapper> 
+            internal-destination="second-start" fox:alt-text="">next 
page-sequence</fo:basic-link></fo:wrapper> 
         (which starts on page <fo:page-number-citation id="7" 
ref-id="second-start"/> and ends on 
         page <fo:page-number-citation-last id="8" 
ref-id="second-end"/>).</fo:block>
       <fo:block id="9" font-family="sans-serif" font-weight="bold" 
space-before="1em" 
@@ -46,7 +46,7 @@
       <fo:block id="11">This block of text contains a footnote<fo:footnote 
id="12"><fo:inline id="13" 
             baseline-shift="super" 
font-size="70%">1</fo:inline><fo:footnote-body id="14"><fo:block 
               id="15">A footnote with a link to the  <fo:wrapper id="16" 
color="blue"><fo:basic-link 
-                  id="17" 
external-destination="http://xmlgraphics.apache.org/fop/";>FOP 
+                  id="17" 
external-destination="http://xmlgraphics.apache.org/fop/"; fox:alt-text="">FOP 
                   
website</fo:basic-link></fo:wrapper></fo:block></fo:footnote-body></fo:footnote>
 
         call.</fo:block>
       <fo:table id="18" space-before="1em" width="100%" table-layout="fixed">

Added: xmlgraphics/fop/trunk/test/java/org/apache/fop/pdf/PDFUATestCase.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/pdf/PDFUATestCase.java?rev=1685770&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/test/java/org/apache/fop/pdf/PDFUATestCase.java 
(added)
+++ xmlgraphics/fop/trunk/test/java/org/apache/fop/pdf/PDFUATestCase.java Tue 
Jun 16 11:46:50 2015
@@ -0,0 +1,84 @@
+/*
+ * 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.awt.geom.Rectangle2D;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.xmlgraphics.util.QName;
+import org.apache.xmlgraphics.xmp.Metadata;
+
+import org.apache.fop.render.pdf.PDFContentGenerator;
+
+public class PDFUATestCase {
+    @Test
+    public void testXMP() throws IOException {
+        PDFDocument doc = new PDFDocument("");
+        doc.getProfile().setPDFUAMode(PDFUAMode.PDFUA_1);
+        Metadata metadata = PDFMetadata.createXMPFromPDFDocument(doc);
+        StringBuilder sb = new StringBuilder();
+        Iterator i = metadata.iterator();
+        while (i.hasNext()) {
+            QName k = (QName) i.next();
+            sb.append(k + ": " + metadata.getProperty(k).getValue() + "\n");
+        }
+        String s = sb.toString();
+        Assert.assertTrue(s, s.contains("pdfuaid:part: 1"));
+    }
+
+    @Test
+    public void testPDF() throws IOException {
+        PDFDocument doc = new PDFDocument("");
+        doc.getRoot().makeTagged();
+        doc.getRoot().setStructTreeRoot(new PDFStructTreeRoot(null));
+        doc.getInfo().setTitle("title");
+        doc.getProfile().setPDFUAMode(PDFUAMode.PDFUA_1);
+        PDFResources resources = new PDFResources(doc);
+        doc.addObject(resources);
+        PDFResourceContext context = new PDFResourceContext(resources);
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        PDFContentGenerator gen = new PDFContentGenerator(doc, out, context);
+        Rectangle2D.Float f = new Rectangle2D.Float();
+        PDFPage page = new PDFPage(resources, 0, f, f, f, f);
+        doc.addImage(context, new BitmapImage("", 1, 1, new byte[0], null));
+        doc.registerObject(page);
+        gen.flushPDFDoc();
+        doc.outputTrailer(out);
+
+        Collection<StringBuilder> objs = PDFLinearizationTestCase.readObjs(
+                new ByteArrayInputStream(out.toByteArray())).values();
+        Assert.assertTrue(getObj(objs, "/Type 
/Catalog").contains("/ViewerPreferences << /DisplayDocTitle true >>"));
+    }
+
+    private String getObj(Collection<StringBuilder> objs, String x) {
+        for (StringBuilder s : objs) {
+            if (s.toString().contains(x)) {
+                return s.toString();
+            }
+        }
+        return null;
+    }
+}

Propchange: 
xmlgraphics/fop/trunk/test/java/org/apache/fop/pdf/PDFUATestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native



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

Reply via email to