diff options
author | Simon Steiner <ssteiner@apache.org> | 2025-01-10 10:05:55 +0000 |
---|---|---|
committer | Simon Steiner <ssteiner@apache.org> | 2025-01-10 10:05:55 +0000 |
commit | 7f201b321490b247ca57b98626ed72da6d52409b (patch) | |
tree | b22f3be60bb6d115a4d9ad33857aba742ed9ea46 | |
parent | fd9046148948ebf7e838156086b47cfbd4c1fada (diff) | |
download | xmlgraphics-fop-7f201b321490b247ca57b98626ed72da6d52409b.tar.gz xmlgraphics-fop-7f201b321490b247ca57b98626ed72da6d52409b.zip |
FOP-3228: Limit embed of only native PDF in AFP
14 files changed, 85 insertions, 9 deletions
diff --git a/fop-core/src/main/java/org/apache/fop/afp/AFPPaintingState.java b/fop-core/src/main/java/org/apache/fop/afp/AFPPaintingState.java index 62303d9ea..c9e8631ef 100644 --- a/fop-core/src/main/java/org/apache/fop/afp/AFPPaintingState.java +++ b/fop-core/src/main/java/org/apache/fop/afp/AFPPaintingState.java @@ -67,6 +67,7 @@ public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState * format. */ private boolean nativeImagesSupported; + private boolean nativePDFImagesSupported; private boolean canEmbedJpeg; @@ -254,6 +255,14 @@ public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState return this.nativeImagesSupported; } + public void setNativePDFImagesSupported(boolean nativePDFImagesSupported) { + this.nativePDFImagesSupported = nativePDFImagesSupported; + } + + public boolean isNativePDFImagesSupported() { + return nativePDFImagesSupported; + } + /** * Set whether or not JPEG images can be embedded within an AFP document. * diff --git a/fop-core/src/main/java/org/apache/fop/render/ImageHandlerRegistry.java b/fop-core/src/main/java/org/apache/fop/render/ImageHandlerRegistry.java index d4d9b89d2..bcccd2a46 100644 --- a/fop-core/src/main/java/org/apache/fop/render/ImageHandlerRegistry.java +++ b/fop-core/src/main/java/org/apache/fop/render/ImageHandlerRegistry.java @@ -142,11 +142,11 @@ public class ImageHandlerRegistry { * @param context the rendering context * @return the array of image flavors */ - public synchronized ImageFlavor[] getSupportedFlavors(RenderingContext context) { + public synchronized ImageFlavor[] getSupportedFlavors(RenderingContext context, Image image) { //Extract all ImageFlavors into a single array List<ImageFlavor> flavors = new java.util.ArrayList<ImageFlavor>(); for (ImageHandler handler : this.handlerList) { - if (handler.isCompatible(context, null)) { + if (handler.isCompatible(context, image)) { ImageFlavor[] f = handler.getSupportedImageFlavors(); Collections.addAll(flavors, f); } diff --git a/fop-core/src/main/java/org/apache/fop/render/afp/AFPDocumentHandler.java b/fop-core/src/main/java/org/apache/fop/render/afp/AFPDocumentHandler.java index b1bb7701d..83a6f5c87 100644 --- a/fop-core/src/main/java/org/apache/fop/render/afp/AFPDocumentHandler.java +++ b/fop-core/src/main/java/org/apache/fop/render/afp/AFPDocumentHandler.java @@ -476,6 +476,10 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler paintingState.setNativeImagesSupported(nativeImages); } + public void setNativePDFImagesSupported(boolean nativeImages) { + paintingState.setNativePDFImagesSupported(nativeImages); + } + /** {@inheritDoc} */ public void setCMYKImagesSupported(boolean value) { paintingState.setCMYKImagesSupported(value); diff --git a/fop-core/src/main/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java b/fop-core/src/main/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java index cc072e318..1fb02f184 100644 --- a/fop-core/src/main/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java +++ b/fop-core/src/main/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java @@ -86,6 +86,9 @@ public class AFPImageHandlerRawStream extends AbstractAFPImageHandlerRawStream { public boolean isCompatible(RenderingContext targetContext, Image image) { if (targetContext instanceof AFPRenderingContext) { AFPRenderingContext afpContext = (AFPRenderingContext)targetContext; + if (afpContext.getPaintingState().isNativePDFImagesSupported() && isPDFCompatible(image)) { + return true; + } return (afpContext.getPaintingState().isNativeImagesSupported()) && (image == null || image instanceof ImageRawJPEG @@ -99,4 +102,12 @@ public class AFPImageHandlerRawStream extends AbstractAFPImageHandlerRawStream { return MimeConstants.MIME_TIFF.equals(rawStream.getMimeType()) || MimeConstants.MIME_PDF.equals(rawStream.getMimeType()); } + + private boolean isPDFCompatible(Image image) { + if (image instanceof ImageRawStream) { + ImageRawStream rawStream = (ImageRawStream)image; + return MimeConstants.MIME_PDF.equals(rawStream.getMimeType()); + } + return false; + } } diff --git a/fop-core/src/main/java/org/apache/fop/render/afp/AFPPainter.java b/fop-core/src/main/java/org/apache/fop/render/afp/AFPPainter.java index 9a4a7b93e..f417621be 100644 --- a/fop-core/src/main/java/org/apache/fop/render/afp/AFPPainter.java +++ b/fop-core/src/main/java/org/apache/fop/render/afp/AFPPainter.java @@ -47,6 +47,7 @@ import org.apache.xmlgraphics.image.loader.ImageProcessingHints; import org.apache.xmlgraphics.image.loader.ImageSessionContext; import org.apache.xmlgraphics.image.loader.ImageSize; import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D; +import org.apache.xmlgraphics.image.loader.impl.ImageRawStream; import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; import org.apache.fop.afp.AFPBorderPainter; @@ -68,6 +69,7 @@ import org.apache.fop.afp.modca.PresentationTextObject; import org.apache.fop.afp.ptoca.PtocaBuilder; import org.apache.fop.afp.ptoca.PtocaProducer; import org.apache.fop.afp.util.AFPResourceAccessor; +import org.apache.fop.apps.MimeConstants; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontTriplet; import org.apache.fop.fonts.Typeface; @@ -1151,4 +1153,15 @@ public class AFPPainter extends AbstractIFPainter<AFPDocumentHandler> { BorderProps bpsAfter, BorderProps bpsStart, BorderProps bpsEnd) throws IFException { // not supported in AFP } + + protected Image getImageForSupportedFlavors(ImageInfo info) { + if (getPaintingState().isNativePDFImagesSupported() && MimeConstants.MIME_PDF.equals(info.getMimeType())) { + return new ImageRawStream(info, null, (ImageRawStream.InputStreamFactory) null) { + public String getMimeType() { + return MimeConstants.MIME_PDF; + } + }; + } + return null; + } } diff --git a/fop-core/src/main/java/org/apache/fop/render/afp/AFPRendererConfig.java b/fop-core/src/main/java/org/apache/fop/render/afp/AFPRendererConfig.java index fe1978a02..9fac18392 100644 --- a/fop-core/src/main/java/org/apache/fop/render/afp/AFPRendererConfig.java +++ b/fop-core/src/main/java/org/apache/fop/render/afp/AFPRendererConfig.java @@ -57,6 +57,7 @@ import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_MAPPING_OPTION; import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_MASK_ENABLED; import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_MODE; import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_NATIVE; +import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_NATIVE_PDF; import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_WRAP_PSEG; import static org.apache.fop.render.afp.AFPRendererOption.JPEG_ALLOW_JPEG_EMBEDDING; import static org.apache.fop.render.afp.AFPRendererOption.JPEG_BITMAP_ENCODING_QUALITY; @@ -148,6 +149,10 @@ public final class AFPRendererConfig implements RendererConfig { return getParam(IMAGES_NATIVE, Boolean.class); } + public Boolean isNativePDFImagesSupported() { + return getParam(IMAGES_NATIVE_PDF, Boolean.class); + } + public AFPShadingMode getShadingMode() { return getParam(SHADING, AFPShadingMode.class); } @@ -322,8 +327,8 @@ public final class AFPRendererConfig implements RendererConfig { } setParam(IMAGES_DITHERING_QUALITY, dq); setParam(IMAGES_NATIVE, imagesCfg.getAttributeAsBoolean(IMAGES_NATIVE.getName(), false)); - setParam(IMAGES_WRAP_PSEG, - imagesCfg.getAttributeAsBoolean(IMAGES_WRAP_PSEG.getName(), false)); + setParam(IMAGES_NATIVE_PDF, imagesCfg.getAttributeAsBoolean(IMAGES_NATIVE_PDF.getName(), false)); + setParam(IMAGES_WRAP_PSEG, imagesCfg.getAttributeAsBoolean(IMAGES_WRAP_PSEG.getName(), false)); setParam(IMAGES_FS45, imagesCfg.getAttributeAsBoolean(IMAGES_FS45.getName(), false)); setParam(IMAGES_MASK_ENABLED, imagesCfg.getAttributeAsBoolean(IMAGES_MASK_ENABLED.getName(), false)); if ("scale-to-fit".equals(imagesCfg.getAttribute(IMAGES_MAPPING_OPTION.getName(), null))) { diff --git a/fop-core/src/main/java/org/apache/fop/render/afp/AFPRendererConfigurator.java b/fop-core/src/main/java/org/apache/fop/render/afp/AFPRendererConfigurator.java index 803a5c0d9..3031e6b37 100644 --- a/fop-core/src/main/java/org/apache/fop/render/afp/AFPRendererConfigurator.java +++ b/fop-core/src/main/java/org/apache/fop/render/afp/AFPRendererConfigurator.java @@ -84,6 +84,9 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator { if (config.isNativeImagesSupported() != null) { documentHandler.setNativeImagesSupported(config.isNativeImagesSupported()); } + if (config.isNativePDFImagesSupported() != null) { + documentHandler.setNativePDFImagesSupported(config.isNativePDFImagesSupported()); + } if (config.getShadingMode() != null) { documentHandler.setShadingMode(config.getShadingMode()); } diff --git a/fop-core/src/main/java/org/apache/fop/render/afp/AFPRendererOption.java b/fop-core/src/main/java/org/apache/fop/render/afp/AFPRendererOption.java index d0721c26e..1e3f44b05 100644 --- a/fop-core/src/main/java/org/apache/fop/render/afp/AFPRendererOption.java +++ b/fop-core/src/main/java/org/apache/fop/render/afp/AFPRendererOption.java @@ -35,6 +35,7 @@ public enum AFPRendererOption implements RendererConfigOption { IMAGES_MAPPING_OPTION("mapping_option", Byte.class), IMAGES_MODE("mode", Boolean.class), IMAGES_NATIVE("native", Boolean.class), + IMAGES_NATIVE_PDF("native-pdf", Boolean.class), IMAGES_WRAP_PSEG("pseg", Boolean.class), JPEG_ALLOW_JPEG_EMBEDDING("allow-embedding", Boolean.class), JPEG_BITMAP_ENCODING_QUALITY("bitmap-encoding-quality", Float.class), diff --git a/fop-core/src/main/java/org/apache/fop/render/intermediate/AbstractIFPainter.java b/fop-core/src/main/java/org/apache/fop/render/intermediate/AbstractIFPainter.java index 85e8435ef..564e6d150 100644 --- a/fop-core/src/main/java/org/apache/fop/render/intermediate/AbstractIFPainter.java +++ b/fop-core/src/main/java/org/apache/fop/render/intermediate/AbstractIFPainter.java @@ -158,7 +158,7 @@ public abstract class AbstractIFPainter<T extends IFDocumentHandler> implements Map hints = createDefaultImageProcessingHints(sessionContext); context.putHints(hints); - ImageFlavor[] flavors = imageHandlerRegistry.getSupportedFlavors(context); + ImageFlavor[] flavors = imageHandlerRegistry.getSupportedFlavors(context, getImageForSupportedFlavors(info)); info.getCustomObjects().put("warningincustomobject", true); org.apache.xmlgraphics.image.loader.Image img = manager.getImage( info, flavors, @@ -181,6 +181,10 @@ public abstract class AbstractIFPainter<T extends IFDocumentHandler> implements } } + protected Image getImageForSupportedFlavors(ImageInfo info) { + return null; + } + /** * Creates the default map of processing hints for the image loading framework. * @param sessionContext the session context for access to resolution information @@ -234,8 +238,7 @@ public abstract class AbstractIFPainter<T extends IFDocumentHandler> implements if (additionalHints != null) { hints.putAll(additionalHints); } - effImage = manager.convertImage(image, - imageHandlerRegistry.getSupportedFlavors(context), hints); + effImage = manager.convertImage(image, imageHandlerRegistry.getSupportedFlavors(context, null), hints); } else { effImage = image; } diff --git a/fop-core/src/main/java/org/apache/fop/render/ps/PSImageUtils.java b/fop-core/src/main/java/org/apache/fop/render/ps/PSImageUtils.java index e9d4ff27f..5e7ecce54 100644 --- a/fop-core/src/main/java/org/apache/fop/render/ps/PSImageUtils.java +++ b/fop-core/src/main/java/org/apache/fop/render/ps/PSImageUtils.java @@ -81,7 +81,7 @@ public class PSImageUtils extends org.apache.xmlgraphics.ps.PSImageUtils { ImageFlavor[] inlineFlavors; ImageHandlerRegistry imageHandlerRegistry = renderingContext.getUserAgent().getImageHandlerRegistry(); - inlineFlavors = imageHandlerRegistry.getSupportedFlavors(renderingContext); + inlineFlavors = imageHandlerRegistry.getSupportedFlavors(renderingContext, null); return inlineFlavors; } diff --git a/fop-core/src/main/java/org/apache/fop/render/ps/ResourceHandler.java b/fop-core/src/main/java/org/apache/fop/render/ps/ResourceHandler.java index 7144aafd6..708a341af 100644 --- a/fop-core/src/main/java/org/apache/fop/render/ps/ResourceHandler.java +++ b/fop-core/src/main/java/org/apache/fop/render/ps/ResourceHandler.java @@ -297,7 +297,7 @@ public class ResourceHandler implements DSCParserConstants, PSSupportedFlavors { ImageFlavor[] flavors; ImageHandlerRegistry imageHandlerRegistry = userAgent.getImageHandlerRegistry(); - flavors = imageHandlerRegistry.getSupportedFlavors(formContext); + flavors = imageHandlerRegistry.getSupportedFlavors(formContext, null); Map hints = ImageUtil.getDefaultHints(sessionContext); org.apache.xmlgraphics.image.loader.Image img = manager.getImage( diff --git a/fop-core/src/test/java/org/apache/fop/apps/AFPRendererConfBuilder.java b/fop-core/src/test/java/org/apache/fop/apps/AFPRendererConfBuilder.java index 130971175..ca0e7c92b 100644 --- a/fop-core/src/test/java/org/apache/fop/apps/AFPRendererConfBuilder.java +++ b/fop-core/src/test/java/org/apache/fop/apps/AFPRendererConfBuilder.java @@ -40,6 +40,7 @@ import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_MAPPING_OPTION; import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_MASK_ENABLED; import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_MODE; import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_NATIVE; +import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_NATIVE_PDF; import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_WRAP_PSEG; import static org.apache.fop.render.afp.AFPRendererOption.JPEG_ALLOW_JPEG_EMBEDDING; import static org.apache.fop.render.afp.AFPRendererOption.JPEG_BITMAP_ENCODING_QUALITY; @@ -174,6 +175,10 @@ public final class AFPRendererConfBuilder extends RendererConfBuilder { return setAttribute(IMAGES_NATIVE, value); } + public ImagesBuilder setNativePDFImageSupport(boolean value) { + return setAttribute(IMAGES_NATIVE_PDF, value); + } + public AFPRendererConfBuilder endImages() { return AFPRendererConfBuilder.this.endImages(); } diff --git a/fop-core/src/test/java/org/apache/fop/render/afp/AFPImageHandlerRawStreamTestCase.java b/fop-core/src/test/java/org/apache/fop/render/afp/AFPImageHandlerRawStreamTestCase.java index 36460ae0d..339daf50f 100644 --- a/fop-core/src/test/java/org/apache/fop/render/afp/AFPImageHandlerRawStreamTestCase.java +++ b/fop-core/src/test/java/org/apache/fop/render/afp/AFPImageHandlerRawStreamTestCase.java @@ -40,4 +40,15 @@ public class AFPImageHandlerRawStreamTestCase { Assert.assertFalse(Arrays.asList( new AFPImageHandlerRawStream().getSupportedImageFlavors()).contains(ImageFlavor.RAW)); } + + @Test + public void testPDFIsCompatible() { + AFPPaintingState state = new AFPPaintingState(); + state.setNativePDFImagesSupported(true); + AFPRenderingContext context = new AFPRenderingContext(null, null, state, null, null); + ImageRawStream stream = new ImageRawStream(null, ImageFlavor.RAW_PDF, (InputStream) null); + Assert.assertTrue(new AFPImageHandlerRawStream().isCompatible(context, stream)); + stream = new ImageRawStream(null, ImageFlavor.RAW_JPEG, (InputStream) null); + Assert.assertFalse(new AFPImageHandlerRawStream().isCompatible(context, stream)); + } } diff --git a/fop-core/src/test/java/org/apache/fop/render/afp/AFPRendererConfigParserTestCase.java b/fop-core/src/test/java/org/apache/fop/render/afp/AFPRendererConfigParserTestCase.java index 640fee564..02f642b9f 100644 --- a/fop-core/src/test/java/org/apache/fop/render/afp/AFPRendererConfigParserTestCase.java +++ b/fop-core/src/test/java/org/apache/fop/render/afp/AFPRendererConfigParserTestCase.java @@ -123,6 +123,17 @@ public class AFPRendererConfigParserTestCase assertEquals(true, conf.isCmykImagesSupported()); } + @Test + public void testNativePDFImages() throws Exception { + parseConfig(); + assertFalse(conf.isNativePDFImagesSupported()); + parseConfig(createRenderer() + .startImages() + .setNativePDFImageSupport(true) + .endImages()); + assertTrue(conf.isNativePDFImagesSupported()); + } + @Test(expected = IllegalStateException.class) public void testImagesException1() throws Exception { parseConfig(createRenderer().startImages().endImages()); |