diff options
author | Vincent Hennebert <vhennebert@apache.org> | 2014-03-14 10:44:23 +0000 |
---|---|---|
committer | Vincent Hennebert <vhennebert@apache.org> | 2014-03-14 10:44:23 +0000 |
commit | 4c131bd42f52e394b4c6220a3af179cb4539bf40 (patch) | |
tree | a5abb4df2edda095317f825c276e863b8a1d081b /src/java | |
parent | 28b4b3d4de6106f807de5836683c82c453d58b9e (diff) | |
download | xmlgraphics-fop-4c131bd42f52e394b4c6220a3af179cb4539bf40.tar.gz xmlgraphics-fop-4c131bd42f52e394b4c6220a3af179cb4539bf40.zip |
FOP-2357: When an SVG image has transparency and a PDF profile is used that disallows it, ignore it and issue a warning rather than throw an error
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1577477 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java')
6 files changed, 87 insertions, 22 deletions
diff --git a/src/java/org/apache/fop/pdf/PDFProfile.java b/src/java/org/apache/fop/pdf/PDFProfile.java index 6e0cb412e..4ae5ba8df 100644 --- a/src/java/org/apache/fop/pdf/PDFProfile.java +++ b/src/java/org/apache/fop/pdf/PDFProfile.java @@ -169,15 +169,28 @@ public class PDFProfile { * @param context Context information for the user to identify the problem spot */ public void verifyTransparencyAllowed(String context) { - final String err = "{0} does not allow the use of transparency. ({1})"; + Object profile = isTransparencyAllowed(); + if (profile != null) { + throw new PDFConformanceException(profile + " does not allow the use of transparency. (" + + profile + ")"); + } + } + + /** + * Returns {@code null} if transparency is allowed, otherwise returns the profile that + * prevents it. + * + * @return {@code null}, or an object whose {@code toString} method returns the name + * of the profile that disallows transparency + */ + public Object isTransparencyAllowed() { if (pdfAMode.isPart1()) { - throw new PDFConformanceException(MessageFormat.format(err, - new Object[] {getPDFAMode(), context})); + return getPDFAMode(); } if (isPDFXActive()) { - throw new PDFConformanceException(MessageFormat.format(err, - new Object[] {getPDFXMode(), context})); + return getPDFXMode(); } + return null; } /** Checks if the right PDF version is set. */ diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java index a71ade911..5ab0b700f 100644 --- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java +++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java @@ -86,7 +86,7 @@ public class PDFImageHandlerGraphics2D extends AbstractImageHandlerGraphics2D { PDFGraphics2D graphics = new PDFGraphics2D(textAsShapes, pdfContext.getFontInfo(), generator.getDocument(), generator.getResourceContext(), pdfContext.getPage().referencePDF(), - "", 0.0f); + "", 0.0f, null); graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); AffineTransform transform = new AffineTransform(); diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java index 3b7084a65..ae282f149 100644 --- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java +++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java @@ -41,6 +41,7 @@ import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; import org.apache.xmlgraphics.util.UnitConv; import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.events.EventBroadcaster; import org.apache.fop.image.loader.batik.BatikImageFlavors; import org.apache.fop.image.loader.batik.BatikUtil; import org.apache.fop.render.ImageHandler; @@ -171,7 +172,7 @@ public class PDFImageHandlerSVG implements ImageHandler { PDFGraphics2D graphics = new PDFGraphics2D(true, pdfContext.getFontInfo(), generator.getDocument(), generator.getResourceContext(), pdfContext.getPage().referencePDF(), - "", 0); + "", 0, new TransparencyIgnoredEventListener(pdfContext, imageSVG)); graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); if (!resolutionScaling.isIdentity()) { @@ -222,6 +223,30 @@ public class PDFImageHandlerSVG implements ImageHandler { } } + private static class TransparencyIgnoredEventListener + implements PDFGraphics2D.TransparencyIgnoredEventListener { + + private final RenderingContext context; + + private final Image image; + + public TransparencyIgnoredEventListener(RenderingContext context, Image image) { + this.context = context; + this.image = image; + } + + private boolean warningIssued; + + public void transparencyIgnored(Object pdfProfile) { + if (!warningIssued) { + EventBroadcaster broadcaster = context.getUserAgent().getEventBroadcaster(); + SVGEventProducer producer = SVGEventProducer.Provider.get(broadcaster); + producer.transparencyIgnored(this, pdfProfile, image.getInfo().getOriginalURI()); + warningIssued = true; + } + } + } + /** {@inheritDoc} */ public int getPriority() { return 400; diff --git a/src/java/org/apache/fop/svg/PDFGraphics2D.java b/src/java/org/apache/fop/svg/PDFGraphics2D.java index 1fcf9f870..42d79a931 100644 --- a/src/java/org/apache/fop/svg/PDFGraphics2D.java +++ b/src/java/org/apache/fop/svg/PDFGraphics2D.java @@ -189,6 +189,17 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand */ protected OutputStream outputStream = null; + private TransparencyIgnoredEventListener transparencyIgnoredEventListener; + + /** + * May be used to give proper feedback to the user when a particular PDF profile is + * being used that disallows transparency. + */ + public interface TransparencyIgnoredEventListener { + + void transparencyIgnored(Object pdfProfile); + } + /** * Create a new PDFGraphics2D with the given pdf document info. * This is used to create a Graphics object for use inside an already @@ -203,7 +214,8 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand * @param size the current font size */ public PDFGraphics2D(boolean textAsShapes, FontInfo fi, PDFDocument doc, - PDFResourceContext page, String pref, String font, float size) { + PDFResourceContext page, String pref, String font, float size, + TransparencyIgnoredEventListener listener) { this(textAsShapes); pdfDoc = doc; this.colorHandler = new PDFColorHandler(doc.getResources()); @@ -213,6 +225,7 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand fontInfo = fi; pageRef = pref; paintingState = new PDFPaintingState(); + this.transparencyIgnoredEventListener = listener; } /** @@ -244,6 +257,7 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand this.nativeCount = g.nativeCount; this.outputStream = g.outputStream; this.ovFontState = g.ovFontState; + this.transparencyIgnoredEventListener = g.transparencyIgnoredEventListener; } /** @@ -977,7 +991,7 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand PDFResourceContext context = new PDFResourceContext(res); PDFGraphics2D pattGraphic = new PDFGraphics2D(textAsShapes, specialFontInfo, pdfDoc, context, getPageReference(), - "", 0); + "", 0, transparencyIgnoredEventListener); pattGraphic.setGraphicContext(new GraphicContext()); pattGraphic.gc.validateTransformStack(); pattGraphic.setRenderingHints(this.getRenderingHints()); @@ -1430,18 +1444,21 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand */ protected void applyAlpha(int fillAlpha, int strokeAlpha) { if (fillAlpha != OPAQUE || strokeAlpha != OPAQUE) { - checkTransparencyAllowed(); - Map<String, Float> vals = new java.util.HashMap<String, Float>(); - if (fillAlpha != OPAQUE) { - vals.put(PDFGState.GSTATE_ALPHA_NONSTROKE, new Float(fillAlpha / 255f)); - } - if (strokeAlpha != OPAQUE) { - vals.put(PDFGState.GSTATE_ALPHA_STROKE, new Float(strokeAlpha / 255f)); + Object profile = isTransparencyAllowed(); + if (profile == null) { + Map<String, Float> vals = new java.util.HashMap<String, Float>(); + if (fillAlpha != OPAQUE) { + vals.put(PDFGState.GSTATE_ALPHA_NONSTROKE, new Float(fillAlpha / 255f)); + } + if (strokeAlpha != OPAQUE) { + vals.put(PDFGState.GSTATE_ALPHA_STROKE, new Float(strokeAlpha / 255f)); + } + PDFGState gstate = pdfDoc.getFactory().makeGState(vals, paintingState.getGState()); + resourceContext.addGState(gstate); + currentStream.write("/" + gstate.getName() + " gs\n"); + } else if (transparencyIgnoredEventListener != null) { + transparencyIgnoredEventListener.transparencyIgnored(profile); } - PDFGState gstate = pdfDoc.getFactory().makeGState( - vals, paintingState.getGState()); - resourceContext.addGState(gstate); - currentStream.write("/" + gstate.getName() + " gs\n"); } } @@ -1686,8 +1703,8 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand } /** Checks whether the use of transparency is allowed. */ - protected void checkTransparencyAllowed() { - pdfDoc.getProfile().verifyTransparencyAllowed("Java2D graphics"); + protected Object isTransparencyAllowed() { + return pdfDoc.getProfile().isTransparencyAllowed(); } /** diff --git a/src/java/org/apache/fop/svg/SVGEventProducer.java b/src/java/org/apache/fop/svg/SVGEventProducer.java index 743649717..6bf7ed100 100644 --- a/src/java/org/apache/fop/svg/SVGEventProducer.java +++ b/src/java/org/apache/fop/svg/SVGEventProducer.java @@ -89,4 +89,13 @@ public interface SVGEventProducer extends EventProducer { */ void svgRenderingError(Object source, Exception e, String uri); + /** + * Transparency has been ignored due to restrictions from the PDF profile being used. + * @param source the event source + * @param pdfProfile the PDF profile + * @param uri the image URI, if available + * @event.severity WARN + */ + void transparencyIgnored(Object source, Object pdfProfile, String uri); + } diff --git a/src/java/org/apache/fop/svg/SVGEventProducer.xml b/src/java/org/apache/fop/svg/SVGEventProducer.xml index 9d229a14b..f5e1d300a 100644 --- a/src/java/org/apache/fop/svg/SVGEventProducer.xml +++ b/src/java/org/apache/fop/svg/SVGEventProducer.xml @@ -22,4 +22,5 @@ <message key="info">SVG info: {message}</message> <message key="svgNotBuilt">SVG graphic could not be built. Reason: {e}</message> <message key="svgRenderingError">SVG graphic could not be rendered. Reason: {e}</message> + <message key="transparencyIgnored">Transparency in an SVG image will be ignored because {pdfProfile} does not allow it[ (see {uri})].</message> </catalogue> |