Author: ssteiner Date: Thu Apr 27 12:30:22 2017 New Revision: 1792873 URL: http://svn.apache.org/viewvc?rev=1792873&view=rev Log: FOP-2251: PDF to Postscript not showing transparency
Added: xmlgraphics/fop-pdf-images/trunk/test/resources/libreoffice.pdf (with props) Modified: xmlgraphics/fop-pdf-images/trunk/lib/xmlgraphics-commons-svn-trunk.jar xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/ImageConverterPDF2G2D.java xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PSPDFGraphics2D.java xmlgraphics/fop-pdf-images/trunk/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java Modified: xmlgraphics/fop-pdf-images/trunk/lib/xmlgraphics-commons-svn-trunk.jar URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/lib/xmlgraphics-commons-svn-trunk.jar?rev=1792873&r1=1792872&r2=1792873&view=diff ============================================================================== Binary files - no diff available. 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=1792873&r1=1792872&r2=1792873&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 Thu Apr 27 12:30:22 2017 @@ -23,12 +23,24 @@ import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.Map; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.pdfbox.cos.COSDictionary; +import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDResources; import org.apache.pdfbox.pdmodel.common.PDRectangle; +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; import org.apache.xmlgraphics.image.loader.Image; @@ -39,16 +51,28 @@ import org.apache.xmlgraphics.image.load import org.apache.xmlgraphics.image.loader.util.ImageUtil; import org.apache.xmlgraphics.java2d.GeneralGraphics2DImagePainter; import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; +import org.apache.xmlgraphics.java2d.ps.PSGraphics2D; import org.apache.xmlgraphics.ps.PSGenerator; /** * Image converter implementation to convert PDF pages into Java2D images. */ public class ImageConverterPDF2G2D extends AbstractImageConverter { + private static final Log LOG = LogFactory.getLog(ImageConverterPDF2G2D.class); /** {@inheritDoc} */ public Image convert(Image src, Map hints) throws ImageException, IOException { + float dpi = 72; + if (hints != null) { + dpi = (Float)hints.get("SOURCE_RESOLUTION"); + if (dpi == 72) { + //note we are doing twice as many pixels because + //the default size is not really good resolution, + //so create an image that is twice the size + dpi *= 2; + } + } checkSourceFlavor(src); assert src instanceof ImagePDF; ImagePDF imgPDF = (ImagePDF)src; @@ -59,7 +83,7 @@ public class ImageConverterPDF2G2D exten PDDocument pddoc = imgPDF.getPDDocument(); Graphics2DImagePainter painter = - new Graphics2DImagePainterPDF(pddoc, selectedPage, imgPDF.getInfo().getOriginalURI()); + new Graphics2DImagePainterPDF(pddoc, dpi, selectedPage, imgPDF.getInfo().getOriginalURI()); ImageGraphics2D g2dImage = new ImageGraphics2D(src.getInfo(), painter); return g2dImage; @@ -85,10 +109,12 @@ public class ImageConverterPDF2G2D exten private final PDPage page; private final PDDocument pdDocument; + private float dpi; private int selectedPage; private String uri; - public Graphics2DImagePainterPDF(PDDocument pddoc, int selectedPage, String uri) { + public Graphics2DImagePainterPDF(PDDocument pddoc, float dpi, int selectedPage, String uri) { + this.dpi = dpi; pdDocument = pddoc; this.selectedPage = selectedPage; page = pdDocument.getPage(selectedPage); @@ -112,6 +138,10 @@ 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())) { + drawPageAsImage(at, g2d); + return; + } at.translate(area.getX(), area.getY()); at.scale(area.getWidth() / mediaBox.getWidth(), area.getHeight() / mediaBox.getHeight()); @@ -122,6 +152,66 @@ public class ImageConverterPDF2G2D exten } } + private void drawPageAsImage(AffineTransform at, Graphics2D g2d) throws IOException { + PDFRenderer renderer = new PDFRenderer(pdDocument); + BufferedImage bi = renderer.renderImageWithDPI(selectedPage, dpi); + at.scale(72 / dpi, 72 / dpi); + g2d.drawImage(bi, at, null); + } + + static class PageUtil { + private List<COSDictionary> visited = new ArrayList<COSDictionary>(); + + private boolean pageHasTransparency(PDResources res) throws IOException { + if (res != null) { + visited.add(res.getCOSObject()); + if (res.getShadingNames() != null) { + for (COSName name : res.getShadingNames()) { + PDShading s = res.getShading(name); + if ((s.getShadingType() != 2 && s.getShadingType() != 3) + || (s.getShadingType() == 3 && s.getFunction().getFunctionType() == 2) + || (s.getShadingType() == 2 + && s.getColorSpace().toString().contains("FunctionType"))) { + LOG.warn(s.getClass().getName() + " not supported converting to image"); + return true; + } +// if (s.getShadingType() == 3) { +// COSArray sourceFunctions = ((PDFunctionType3)s.getFunction()).getFunctions(); +// for (COSBase sf : sourceFunctions) { +// PDFunction f = PDFunction.create(sf); +// if (f.getFunctionType() == 2) { +// LOG.warn(s.getClass().getName() + " not supported converting to image"); +// return true; +// } +// } +// } + } + } + for (COSName pdxObjectName : res.getXObjectNames()) { + PDXObject pdxObject = res.getXObject(pdxObjectName); + if (pdxObject instanceof PDFormXObject) { + PDFormXObject form = (PDFormXObject) pdxObject; + if (form.getGroup() != null && COSName.TRANSPARENCY.equals( + form.getGroup().getCOSObject().getDictionaryObject(COSName.S))) { + return true; + } + PDResources formRes = form.getResources(); + if (formRes != null && !visited.contains(formRes.getCOSObject()) + && pageHasTransparency(formRes)) { + return true; + } + } else if (pdxObject instanceof PDImageXObject) { + if (pdxObject.getCOSStream().containsKey(COSName.SMASK) + || ((PDImageXObject) pdxObject).isStencil()) { + return true; + } + } + } + } + return false; + } + } + public Graphics2D getGraphics(boolean textAsShapes, PSGenerator gen) { PSPDFGraphics2D graphics = new PSPDFGraphics2D(textAsShapes, gen); return graphics; Modified: xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PSPDFGraphics2D.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PSPDFGraphics2D.java?rev=1792873&r1=1792872&r2=1792873&view=diff ============================================================================== --- xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PSPDFGraphics2D.java (original) +++ xmlgraphics/fop-pdf-images/trunk/src/java/org/apache/fop/render/pdf/pdfbox/PSPDFGraphics2D.java Thu Apr 27 12:30:22 2017 @@ -29,6 +29,7 @@ import java.awt.PaintContext; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; import java.awt.image.DataBufferInt; import java.awt.image.ImageObserver; import java.io.BufferedOutputStream; @@ -240,9 +241,13 @@ public class PSPDFGraphics2D extends PSG @Override public boolean drawImage(Image img, int x1, int y1, ImageObserver observer) { - PSGenerator tmp = gen; + Color mask = null; + ColorModel cm = ((BufferedImage)img).getColorModel(); + if (cm.hasAlpha()) { + mask = Color.WHITE; + } if (gen instanceof PSDocumentHandler.FOPPSGenerator) { - PSDocumentHandler.FOPPSGenerator fopGen = (PSDocumentHandler.FOPPSGenerator)tmp; + PSDocumentHandler.FOPPSGenerator fopGen = (PSDocumentHandler.FOPPSGenerator)gen; PSDocumentHandler handler = fopGen.getHandler(); if (handler.getPSUtil().isOptimizeResources()) { try { @@ -292,7 +297,7 @@ public class PSPDFGraphics2D extends PSG return true; } } - return super.drawImage(img, x1, y1, observer); + return super.drawImage(img, x1, y1, observer, mask); } private BufferedImage getImage(int width, int height, Image img, ImageObserver observer) { 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=1792873&r1=1792872&r2=1792873&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 Thu Apr 27 12:30:22 2017 @@ -108,6 +108,7 @@ public class PDFBoxAdapterTestCase { private static final String XFORM = "test/resources/xform.pdf"; private static final String LOOP = "test/resources/loop.pdf"; private static final String ERROR = "test/resources/error.pdf"; + private static final String LIBREOFFICE = "test/resources/libreoffice.pdf"; private static PDFPage getPDFPage(PDFDocument doc) { final Rectangle2D r = new Rectangle2D.Double(); @@ -286,8 +287,7 @@ public class PDFBoxAdapterTestCase { @Test public void testPSPDFGraphics2D() throws Exception { ByteArrayOutputStream stream = pdfToPS(IMAGE); - Assert.assertTrue(stream.toString("UTF-8"), - stream.toString("UTF-8").contains("%%IncludeResource: form FOPForm:0\nFOPForm:0 execform")); + Assert.assertEquals(countString(stream.toString("UTF-8"), "%AXGBeginBitmap:"), 1); pdfToPS(CFF1); pdfToPS(CFF2); @@ -298,7 +298,8 @@ public class PDFBoxAdapterTestCase { pdfToPS(TTSubset2); pdfToPS(TTSubset3); pdfToPS(TTSubset5); - pdfToPS(CFFCID1); + stream = pdfToPS(CFFCID1); + Assert.assertEquals(countString(stream.toString("UTF-8"), "%AXGBeginBitmap:"), 1); pdfToPS(CFFCID2); pdfToPS(Type1Subset1); pdfToPS(Type1Subset2); @@ -307,6 +308,13 @@ public class PDFBoxAdapterTestCase { pdfToPS(ROTATE); pdfToPS(LINK); pdfToPS(LOOP); + stream = pdfToPS(LIBREOFFICE); + Assert.assertTrue(stream.toString("UTF-8").contains("/MaskColor [ 255 255 255 ]")); + + } + + private int countString(String s, String value) { + return s.split(value).length - 1; } @Test @@ -359,7 +367,7 @@ public class PDFBoxAdapterTestCase { public PSDocumentHandler getHandler() { PSDocumentHandler handler = mock(PSDocumentHandler.class); PSRenderingUtil util = mock(PSRenderingUtil.class); - when(util.isOptimizeResources()).thenReturn(true); + when(util.isOptimizeResources()).thenReturn(false); when(handler.getPSUtil()).thenReturn(util); FOUserAgent mockedAgent = mock(FOUserAgent.class); when(handler.getUserAgent()).thenReturn(mockedAgent); Added: xmlgraphics/fop-pdf-images/trunk/test/resources/libreoffice.pdf URL: http://svn.apache.org/viewvc/xmlgraphics/fop-pdf-images/trunk/test/resources/libreoffice.pdf?rev=1792873&view=auto ============================================================================== Binary file - no diff available. Propchange: xmlgraphics/fop-pdf-images/trunk/test/resources/libreoffice.pdf ------------------------------------------------------------------------------ svn:executable = * Propchange: xmlgraphics/fop-pdf-images/trunk/test/resources/libreoffice.pdf ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream --------------------------------------------------------------------- To unsubscribe, e-mail: fop-commits-unsubscr...@xmlgraphics.apache.org For additional commands, e-mail: fop-commits-h...@xmlgraphics.apache.org