FOP-2739: Avoid rastering PDF with Smask to image
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop-pdf-images/trunk@1808727 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/xmlgraphics-commons-svn-trunk.jar b/lib/xmlgraphics-commons-svn-trunk.jar
index 4b3afff..fe78fa4 100644
--- a/lib/xmlgraphics-commons-svn-trunk.jar
+++ b/lib/xmlgraphics-commons-svn-trunk.jar
Binary files differ
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/ImageConverterPDF2G2D.java b/src/java/org/apache/fop/render/pdf/pdfbox/ImageConverterPDF2G2D.java
index e63a6eb..c7d9a47 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/ImageConverterPDF2G2D.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/ImageConverterPDF2G2D.java
@@ -39,7 +39,6 @@
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;
@@ -202,11 +201,6 @@
&& pageHasTransparency(formRes)) {
return true;
}
- } else if (pdxObject instanceof PDImageXObject) {
- if (pdxObject.getCOSStream().containsKey(COSName.SMASK)
- || ((PDImageXObject) pdxObject).isStencil()) {
- return true;
- }
}
}
}
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/PSPDFGraphics2D.java b/src/java/org/apache/fop/render/pdf/pdfbox/PSPDFGraphics2D.java
index ad7c847..761d363 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/PSPDFGraphics2D.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/PSPDFGraphics2D.java
@@ -27,7 +27,10 @@
import java.awt.Paint;
import java.awt.PaintContext;
import java.awt.Rectangle;
+import java.awt.TexturePaint;
import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBufferInt;
@@ -148,9 +151,43 @@
handleIOException(ioe);
}
}
+ } else if (paint.getClass().getSimpleName().equals("TilingPaint")) {
+ try {
+ Field f = paint.getClass().getDeclaredField("paint");
+ f.setAccessible(true);
+ TexturePaint texturePaint = (TexturePaint) f.get(paint);
+ f = paint.getClass().getDeclaredField("patternMatrix");
+ f.setAccessible(true);
+ Matrix matrix = (Matrix) f.get(paint);
+ Rectangle2D rect = getTransformedRect(matrix, texturePaint.getAnchorRect());
+ texturePaint = new TexturePaint(texturePaint.getImage(), rect);
+ super.applyPaint(texturePaint, fill);
+ } catch (NoSuchFieldException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
}
}
+ private static Rectangle2D getTransformedRect(Matrix matrix, Rectangle2D anchorRect) {
+ double x = anchorRect.getX();
+ double y = anchorRect.getY();
+ double width = anchorRect.getWidth();
+ double height = anchorRect.getHeight();
+ AffineTransform at = matrix.createAffineTransform();
+ Point2D p1 = new Point2D.Double(x, y);
+ Point2D p2 = new Point2D.Double(x + width, y + height);
+ at.transform(p1, p1);
+ at.transform(p2, p2);
+ Rectangle2D rectangle = new Rectangle2D.Float(
+ (float) Math.min(p1.getX(), p2.getX()),
+ (float) Math.min(p1.getY(), p2.getY()),
+ (float) Math.abs(width),
+ (float) Math.abs(height));
+ return rectangle;
+ }
+
private void transformCoords(float[] coords, Paint paint, boolean axialShading) {
try {
Field f = paint.getClass().getDeclaredField("matrix");
diff --git a/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java b/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
index e18ea45..a8507cb 100644
--- a/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
@@ -112,6 +112,7 @@
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 final String SMASK = "test/resources/smask.pdf";
private static PDFPage getPDFPage(PDFDocument doc) {
final Rectangle2D r = new Rectangle2D.Double();
@@ -299,7 +300,7 @@
pdfToPS(TTSubset3);
pdfToPS(TTSubset5);
stream = pdfToPS(CFFCID1);
- Assert.assertEquals(countString(stream.toString("UTF-8"), "%AXGBeginBitmap:"), 1);
+ Assert.assertEquals(countString(stream.toString("UTF-8"), "%AXGBeginBitmap:"), 2);
pdfToPS(CFFCID2);
pdfToPS(Type1Subset1);
pdfToPS(Type1Subset2);
@@ -360,6 +361,13 @@
}
@Test
+ public void testSmask() throws IOException, ImageException {
+ ByteArrayOutputStream ps = pdfToPS(SMASK);
+ Assert.assertTrue(ps.toString("UTF-8").contains("/Pattern"));
+ Assert.assertTrue(ps.toString("UTF-8").contains("{<\nf1f1f1"));
+ }
+
+ @Test
public void testPCL() throws IOException, ImageException {
String ex = "";
try {
diff --git a/test/resources/smask.pdf b/test/resources/smask.pdf
new file mode 100644
index 0000000..9407e10
--- /dev/null
+++ b/test/resources/smask.pdf
Binary files differ