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 ss...@apache.org on 2019/02/15 09:38:21 UTC

svn commit: r1853627 - in /xmlgraphics/fop-pdf-images/trunk: src/java/org/apache/fop/render/pdf/pdfbox/ test/java/org/apache/fop/render/pdf/

Author: ssteiner
Date: Fri Feb 15 09:38:21 2019
New Revision: 1853627

URL: http://svn.apache.org/viewvc?rev=1853627&view=rev
Log:
FOP-2840: Image mask in PDF not rendered to PS

Modified:
    xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/ImageConverterPDF2G2D.java
    xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/ImageConverterPDF2G2DTestCase.java
    xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java

Modified: xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/ImageConverterPDF2G2D.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/ImageConverterPDF2G2D.java?rev=1853627&r1=1853626&r2=1853627&view=diff
==============================================================================
--- xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/ImageConverterPDF2G2D.java (original)
+++ xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/ImageConverterPDF2G2D.java Fri Feb 15 09:38:21 2019
@@ -37,7 +37,13 @@ import org.apache.commons.logging.LogFac
 import org.apache.fontbox.FontBoxFont;
 import org.apache.fontbox.ttf.TTFParser;
 import org.apache.fontbox.ttf.TrueTypeFont;
+import org.apache.pdfbox.contentstream.PDFStreamEngine;
+import org.apache.pdfbox.contentstream.operator.Operator;
+import org.apache.pdfbox.contentstream.operator.color.SetNonStrokingDeviceGrayColor;
+import org.apache.pdfbox.contentstream.operator.graphics.DrawObject;
+import org.apache.pdfbox.cos.COSBase;
 import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSInteger;
 import org.apache.pdfbox.cos.COSName;
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.pdmodel.PDPage;
@@ -51,6 +57,7 @@ import org.apache.pdfbox.pdmodel.font.PD
 import org.apache.pdfbox.pdmodel.font.PDFontDescriptor;
 import org.apache.pdfbox.pdmodel.graphics.PDXObject;
 import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
+import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
 import org.apache.pdfbox.pdmodel.graphics.shading.PDShading;
 import org.apache.pdfbox.rendering.PDFRenderer;
 
@@ -158,7 +165,7 @@ public class ImageConverterPDF2G2D exten
                 if (rotation == 90 || rotation == 270) {
                     at.scale(area.getWidth() / area.getHeight(), area.getHeight() / area.getWidth());
                 }
-                if (g2d instanceof PSGraphics2D && new PageUtil().pageHasTransparency(page.getResources())) {
+                if (g2d instanceof PSGraphics2D && new PageUtil().pageHasTransparency(page.getResources(), page)) {
                     drawPageAsImage(at, g2d);
                 } else {
                     at.translate(area.getX(), area.getY());
@@ -197,8 +204,9 @@ public class ImageConverterPDF2G2D exten
 
         static class PageUtil {
             private List<COSDictionary> visited = new ArrayList<COSDictionary>();
+            private Map<String, PDXObject> visitedXOjects = new HashMap<String, PDXObject>();
 
-            private boolean pageHasTransparency(PDResources res) throws IOException {
+            private boolean pageHasTransparency(PDResources res, final PDPage page) throws IOException {
                 if (res != null) {
                     visited.add(res.getCOSObject());
                     if (res.getShadingNames() != null) {
@@ -225,6 +233,7 @@ public class ImageConverterPDF2G2D exten
                     }
                     for (COSName pdxObjectName : res.getXObjectNames()) {
                         PDXObject pdxObject = res.getXObject(pdxObjectName);
+                        visitedXOjects.put(pdxObjectName.getName(), pdxObject);
                         if (pdxObject instanceof PDFormXObject) {
                             PDFormXObject form = (PDFormXObject) pdxObject;
                             if (form.getGroup() != null && COSName.TRANSPARENCY.equals(
@@ -233,13 +242,14 @@ public class ImageConverterPDF2G2D exten
                             }
                             PDResources formRes = form.getResources();
                             if (formRes != null && !visited.contains(formRes.getCOSObject())
-                                    && pageHasTransparency(formRes)) {
+                                    && pageHasTransparency(formRes, page)) {
                                 return true;
                             }
                         }
                     }
                 }
-                return false;
+                CheckImageMask checkImageMask = new CheckImageMask(visitedXOjects, page);
+                return checkImageMask.foundWhite;
             }
         }
 
@@ -253,6 +263,48 @@ public class ImageConverterPDF2G2D exten
         }
     }
 
+    static final class CheckImageMask extends PDFStreamEngine {
+        private static final String DRAWOBJECT = new DrawObject().getName();
+        private static final String SETNONSTROKINGDEVICEGRAYCOLOR = new SetNonStrokingDeviceGrayColor().getName();
+        private boolean foundWhite;
+        private boolean checkColor;
+        private Map<String, PDXObject> xobjects;
+        private PDPage page;
+
+        private CheckImageMask(Map<String, PDXObject> visitedXOjects, PDPage page) throws IOException {
+            xobjects = visitedXOjects;
+            this.page = page;
+            for (PDXObject pdxObject : xobjects.values()) {
+                if (pdxObject instanceof PDImageXObject) {
+                    if (((PDImageXObject) pdxObject).isStencil()) {
+                        processChildStream(page, page);
+                        return;
+                    }
+                }
+            }
+        }
+
+        protected void processOperator(Operator operator, List<COSBase> arguments) throws IOException {
+            if (!foundWhite) {
+                String op = operator.getName();
+                if (checkColor && op.equals(SETNONSTROKINGDEVICEGRAYCOLOR)) {
+                    COSBase color = arguments.get(0);
+                    if (color instanceof COSInteger && ((COSInteger) color).intValue() == 1) {
+                        foundWhite = true;
+                    }
+                } else if (op.equals(DRAWOBJECT)) {
+                    COSName name = (COSName) arguments.get(0);
+                    PDXObject xobject = xobjects.get(name.getName());
+                    if (xobject instanceof PDFormXObject) {
+                        checkColor = true;
+                        processChildStream((PDFormXObject)xobject, page);
+                    }
+                    checkColor = false;
+                }
+            }
+        }
+    }
+
     static class FopFontProvider {
         private static FopFontMapper fopFontMapper = new FopFontMapper();
         static {

Modified: xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/ImageConverterPDF2G2DTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/ImageConverterPDF2G2DTestCase.java?rev=1853627&r1=1853626&r2=1853627&view=diff
==============================================================================
--- xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/ImageConverterPDF2G2DTestCase.java (original)
+++ xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/ImageConverterPDF2G2DTestCase.java Fri Feb 15 09:38:21 2019
@@ -25,11 +25,16 @@ import java.awt.image.BufferedImage;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
+import java.io.OutputStream;
 
 import org.junit.Assert;
 import org.junit.Test;
 
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSStream;
 import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.common.PDStream;
+import org.apache.pdfbox.pdmodel.graphics.PDXObject;
 
 import org.apache.xmlgraphics.image.loader.ImageException;
 import org.apache.xmlgraphics.image.loader.ImageInfo;
@@ -61,13 +66,19 @@ public class ImageConverterPDF2G2DTestCa
     }
 
     private boolean pdfToPS(String pdf, String font) throws IOException, ImageException {
+        PDDocument doc = PDDocument.load(new File(pdf));
+        MyLazyFont lazyFont = new MyLazyFont();
+        pdfToPS(doc, pdf, font, lazyFont);
+        return lazyFont.font.fontUsed;
+    }
+
+    private String pdfToPS(PDDocument doc, String pdf, String font, MyLazyFont lazyFont)
+            throws IOException, ImageException {
         ImageConverterPDF2G2D i = new ImageConverterPDF2G2D();
         ImageInfo imgi = new ImageInfo(pdf, "b");
-        PDDocument doc = PDDocument.load(new File(pdf));
         org.apache.xmlgraphics.image.loader.Image img = new ImagePDF(imgi, doc);
         ImageGraphics2D ig = (ImageGraphics2D)i.convert(img, null);
         GeneralGraphics2DImagePainter g = (GeneralGraphics2DImagePainter) ig.getGraphics2DImagePainter();
-        MyLazyFont lazyFont = new MyLazyFont();
         g.addFallbackFont(font, lazyFont);
         ByteArrayOutputStream stream = new ByteArrayOutputStream();
         PSPDFGraphics2D g2d = (PSPDFGraphics2D)
@@ -77,7 +88,7 @@ public class ImageConverterPDF2G2DTestCa
         g2d.setGraphicContext(gc);
         g.paint(g2d, rect);
         doc.close();
-        return lazyFont.font.fontUsed;
+        return stream.toString("UTF-8");
     }
 
     static class MyLazyFont extends LazyFont {
@@ -114,4 +125,24 @@ public class ImageConverterPDF2G2DTestCa
         doc.close();
         Assert.assertEquals(graphics2D.getTransform().getScaleX(), 1.63, 0);
     }
+
+    @Test
+    public void testCheckImageMask() throws IOException, ImageException {
+        String pdf = PDFBoxAdapterTestCase.CFFCID1;
+        PDDocument doc = PDDocument.load(new File(pdf));
+        COSStream cosStream = new COSStream();
+        OutputStream outputStream = cosStream.createOutputStream();
+        outputStream.write("/Fm0 Do\n".getBytes("UTF-8"));
+        outputStream.close();
+        PDStream pdStream = new PDStream(cosStream);
+        doc.getPage(0).setContents(pdStream);
+
+        PDXObject form = doc.getPage(0).getResources().getXObject(COSName.getPDFName("Fm0"));
+        OutputStream formStream = form.getCOSObject().createOutputStream();
+        formStream.write("1 g".getBytes("UTF-8"));
+        formStream.close();
+
+        String ps = pdfToPS(doc, pdf, null, null);
+        Assert.assertTrue(ps.contains("/ImageType 1"));
+    }
 }

Modified: xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java?rev=1853627&r1=1853626&r2=1853627&view=diff
==============================================================================
--- xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java (original)
+++ xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java Fri Feb 15 09:38:21 2019
@@ -97,7 +97,7 @@ public class PDFBoxAdapterTestCase {
     protected static final String TTSubset2 = "test/resources/ttsubset2.pdf";
     private static final String TTSubset3 = "test/resources/ttsubset3.pdf";
     private static final String TTSubset5 = "test/resources/ttsubset5.pdf";
-    private static final String CFFCID1 = "test/resources/cffcid1.pdf";
+    protected static final String CFFCID1 = "test/resources/cffcid1.pdf";
     private static final String CFFCID2 = "test/resources/cffcid2.pdf";
     protected static final String Type1Subset1 = "test/resources/t1subset.pdf";
     protected static final String Type1Subset2 = "test/resources/t1subset2.pdf";



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