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
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.