]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
FOP-2926: Add artifact type to PDF header/footer
authorSimon Steiner <ssteiner@apache.org>
Wed, 25 Mar 2020 16:36:47 +0000 (16:36 +0000)
committerSimon Steiner <ssteiner@apache.org>
Wed, 25 Mar 2020 16:36:47 +0000 (16:36 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1875656 13f79535-47bb-0310-9956-ffa450edef68

fop-core/src/main/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
fop-core/src/main/java/org/apache/fop/render/intermediate/IFContext.java
fop-core/src/main/java/org/apache/fop/render/intermediate/IFParser.java
fop-core/src/main/java/org/apache/fop/render/intermediate/IFRenderer.java
fop-core/src/main/java/org/apache/fop/render/intermediate/IFSerializer.java
fop-core/src/main/java/org/apache/fop/render/pdf/PDFContentGenerator.java
fop-core/src/main/java/org/apache/fop/render/pdf/PDFDocumentHandler.java
fop-core/src/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java

index 19383be00ad190f50db1b66e2ecde52061c6c79a..45996a2f429698e3361a740b3aa4ad090095b0b3 100644 (file)
@@ -91,7 +91,7 @@ public abstract class AbstractIFPainter<T extends IFDocumentHandler> implements
      * Returns the intermediate format context object.
      * @return the context object
      */
-    protected IFContext getContext() {
+    public IFContext getContext() {
         return documentHandler.getContext();
     }
 
index 6f5163a11396dc570835277a251c14b19e931bcb..9c414174c7def22a5de6ef77a8956b2c22789b8e 100644 (file)
@@ -27,6 +27,7 @@ import org.apache.xmlgraphics.util.QName;
 
 import org.apache.fop.accessibility.StructureTreeElement;
 import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fo.Constants;
 
 /**
  * This class provides a context object that is valid for a single processing run to create
@@ -59,6 +60,8 @@ public class IFContext implements PageIndexContext {
 
     private int pageNumber = -1;
 
+    private RegionType regionType;
+
     /**
      * Main constructor.
      * @param ua the user agent
@@ -243,4 +246,32 @@ public class IFContext implements PageIndexContext {
     public void setPageNumber(int pageNumber) {
         this.pageNumber = pageNumber;
     }
+
+    private enum RegionType {
+        Footer,
+        Header
+    }
+
+    public String getRegionType() {
+        if (regionType != null) {
+            return regionType.name();
+        }
+        return null;
+    }
+
+    public void setRegionType(String type) {
+        regionType = null;
+        if (type != null) {
+            regionType = RegionType.valueOf(type);
+        }
+    }
+
+    public void setRegionType(int type) {
+        regionType = null;
+        if (type == Constants.FO_REGION_AFTER) {
+            regionType = RegionType.Footer;
+        } else if (type == Constants.FO_REGION_BEFORE) {
+            regionType = RegionType.Header;
+        }
+    }
 }
index 241d74fc3df84f060eb271909c22c4f507749378..3745da00e5f0317a6cc5fd2d97d6eb6dca3de332 100644 (file)
@@ -582,6 +582,7 @@ public class IFParser implements IFConstants {
                 int height = Integer.parseInt(attributes.getValue("height"));
                 Rectangle clipRect = XMLUtil.getAttributeAsRectangle(attributes, "clip-rect");
                 painter.startViewport(transforms, new Dimension(width, height), clipRect);
+                documentHandler.getContext().setRegionType(attributes.getValue("region-type"));
             }
 
             public void endElement() throws IFException {
index c0c70934c4d9fd578c0471e4517b1da6dbcddcf1..5a401b1a72ecfbf61777f21f68617ef7180bfff1 100644 (file)
@@ -734,6 +734,7 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
     protected void renderRegionViewport(RegionViewport viewport) {
         Dimension dim = new Dimension(viewport.getIPD(), viewport.getBPD());
         viewportDimensionStack.push(dim);
+        documentHandler.getContext().setRegionType(viewport.getRegionReference().getRegionClass());
         super.renderRegionViewport(viewport);
         viewportDimensionStack.pop();
     }
index d12c13b35f0f3b9e63f51e35f2150c2489a54804..ee6557d43d4b6b85e083da0518e9c0f2dfcba026 100644 (file)
@@ -420,6 +420,9 @@ implements IFConstants, IFPainter, IFDocumentNavigationHandler {
             if (clipRect != null) {
                 addAttribute(atts, "clip-rect", IFUtil.toString(clipRect));
             }
+            if (getUserAgent().isAccessibilityEnabled() && getContext().getRegionType() != null) {
+                addAttribute(atts, "region-type", getContext().getRegionType());
+            }
             handler.startElement(EL_VIEWPORT, atts);
         } catch (SAXException e) {
             throw new IFException("SAX error in startViewport()", e);
index 4c6af0dc2ab02471032e90de9ce03b7115d5ab03..c11df3c9461925aa8b093e47fda49156273f2065 100644 (file)
@@ -37,6 +37,7 @@ import org.apache.fop.pdf.PDFStream;
 import org.apache.fop.pdf.PDFText;
 import org.apache.fop.pdf.PDFTextUtil;
 import org.apache.fop.pdf.PDFXObject;
+import org.apache.fop.render.intermediate.IFContext;
 
 /**
  * Generator class encapsulating all object references and state necessary to generate a
@@ -64,6 +65,7 @@ public class PDFContentGenerator {
     private boolean inMarkedContentSequence;
     private boolean inArtifactMode;
     private AffineTransform transform;
+    private IFContext context;
 
     /**
      * Main constructor. Creates a new PDF stream and additional helper classes for text painting
@@ -73,7 +75,12 @@ public class PDFContentGenerator {
      * @param resourceContext the resource context
      */
     public PDFContentGenerator(PDFDocument document, OutputStream out,
-            PDFResourceContext resourceContext) {
+                               PDFResourceContext resourceContext) {
+        this(document, out, resourceContext, null);
+    }
+
+    public PDFContentGenerator(PDFDocument document, OutputStream out,
+                               PDFResourceContext resourceContext, IFContext context) {
         this.document = document;
         this.outputStream = out;
         this.resourceContext = resourceContext;
@@ -90,6 +97,7 @@ public class PDFContentGenerator {
 
         this.currentState = new PDFPaintingState();
         this.colorHandler = new PDFColorHandler(document.getResources());
+        this.context = context;
     }
 
     public AffineTransform getAffineTransform() {
@@ -225,7 +233,11 @@ public class PDFContentGenerator {
                     + actualTextProperty + ">>\n"
                     + "BDC\n");
         } else {
-            getStream().add("/Artifact\nBMC\n");
+            if (context != null && context.getRegionType() != null) {
+                getStream().add("/Artifact\n<</Type /Pagination\n/Subtype /" + context.getRegionType() + ">>\nBDC\n");
+            } else {
+                getStream().add("/Artifact\nBMC\n");
+            }
             this.inArtifactMode = true;
         }
         this.inMarkedContentSequence = true;
index da69fae636d0955c550c9fce928af0822121e6d3..ae2053061fc71a33cbb677537ff6ddd0cfef8ee4 100644 (file)
@@ -257,8 +257,7 @@ public class PDFDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
         currentPageRef = new PageReference(currentPage, size);
         this.pageReferences.put(index, currentPageRef);
 
-        this.generator = new PDFContentGenerator(this.pdfDoc, this.outputStream,
-                this.currentPage);
+        this.generator = new PDFContentGenerator(this.pdfDoc, this.outputStream, this.currentPage, getContext());
         // Transform the PDF's default coordinate system (0,0 at lower left) to the PDFPainter's
         AffineTransform basicPageTransform = new AffineTransform(1, 0, 0, -1, 0,
                 (scaleY * size.height) / 1000f);
index 1c9c685f6826872af2cd12b42517aa04b5cc256d..d0a29abcdc1ac2adc48a61aecd9f9d3268e8824c 100644 (file)
@@ -50,6 +50,7 @@ import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.fonts.MultiByteFont;
 import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.pdf.PDFFilterList;
 import org.apache.fop.pdf.PDFPage;
 import org.apache.fop.pdf.PDFProfile;
 import org.apache.fop.pdf.PDFResources;
@@ -260,4 +261,48 @@ public class PDFPainterTestCase {
         structElem.output(bos);
         return bos.toString();
     }
+
+    @Test
+    public void testFooterText() throws IFException, IOException {
+        FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
+        foUserAgent = fopFactory.newFOUserAgent();
+        foUserAgent.setAccessibility(true);
+        PDFDocumentHandler pdfDocumentHandler = new PDFDocumentHandler(new IFContext(foUserAgent));
+        pdfDocumentHandler.getStructureTreeEventHandler();
+
+        pdfDocumentHandler.setResult(new StreamResult(new ByteArrayOutputStream()));
+        pdfDocumentHandler.startDocument();
+        pdfDocumentHandler.startPage(0, "", "", new Dimension());
+
+        FontInfo fi = new FontInfo();
+        fi.addFontProperties("f1", new FontTriplet("a", "italic", 700));
+        MultiByteFont font = new MultiByteFont(null, null);
+        font.setWidthArray(new int[1]);
+        fi.addMetrics("f1", font);
+        pdfDocumentHandler.setFontInfo(fi);
+        PDFDocument doc = pdfDocumentHandler.getPDFDocument();
+        PDFLogicalStructureHandler structureHandler = new PDFLogicalStructureHandler(doc);
+        MyPDFPainter pdfPainter = new MyPDFPainter(pdfDocumentHandler, structureHandler);
+        pdfPainter.getContext().setRegionType(Constants.FO_REGION_AFTER);
+        pdfPainter.setFont("a", "italic", 700, null, 12, null);
+        pdfPainter.drawText(0, 0, 0, 0, null, "test");
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        PDFFilterList filters = pdfPainter.generator.getStream().getFilterList();
+        filters.setDisableAllFilters(true);
+        pdfPainter.generator.getStream().output(bos);
+        Assert.assertEquals(bos.toString(), "<< /Length 1 0 R >>\n"
+                + "stream\n"
+                + "q\n"
+                + "1 0 0 -1 0 0 cm\n"
+                + "/Artifact\n"
+                + "<</Type /Pagination\n"
+                + "/Subtype /Footer>>\n"
+                + "BDC\n"
+                + "BT\n"
+                + "/f1 0.012 Tf\n"
+                + "1 0 0 -1 0 0 Tm [<0000000000000000>] TJ\n"
+                + "\n"
+                + "endstream");
+    }
 }