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