From: Simon Steiner Date: Thu, 6 Jun 2024 15:09:34 +0000 (+0100) Subject: FOP-3184: Allow change of resource level for SVG in AFP X-Git-Tag: 2_10~26 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=742784c4a90d18174682aa871b8d4b35a2ea2d1d;p=xmlgraphics-fop.git FOP-3184: Allow change of resource level for SVG in AFP --- diff --git a/fop-core/src/main/java/org/apache/fop/afp/AFPResourceLevelDefaults.java b/fop-core/src/main/java/org/apache/fop/afp/AFPResourceLevelDefaults.java index f1df49b62..381d0a7ad 100644 --- a/fop-core/src/main/java/org/apache/fop/afp/AFPResourceLevelDefaults.java +++ b/fop-core/src/main/java/org/apache/fop/afp/AFPResourceLevelDefaults.java @@ -30,11 +30,13 @@ import org.apache.fop.afp.modca.ResourceObject; public class AFPResourceLevelDefaults { private static final Map RESOURCE_TYPE_NAMES = new java.util.HashMap(); + public static final byte TYPE_SVG = Byte.MAX_VALUE; static { //Map to be extended as need arises: registerResourceTypeName("goca", ResourceObject.TYPE_GRAPHIC); registerResourceTypeName("bitmap", ResourceObject.TYPE_IMAGE); + registerResourceTypeName("svg", TYPE_SVG); } private static void registerResourceTypeName(String name, byte type) { @@ -59,6 +61,7 @@ public class AFPResourceLevelDefaults { // (due to a bug in the IBM AFP Workbench Viewer (2.04.01.07), hard copy works just fine) setDefaultResourceLevel(ResourceObject.TYPE_GRAPHIC, new AFPResourceLevel(ResourceType.INLINE)); + setDefaultResourceLevel(TYPE_SVG, new AFPResourceLevel(ResourceType.INLINE)); } /** diff --git a/fop-core/src/main/java/org/apache/fop/render/afp/AFPImageHandlerSVG.java b/fop-core/src/main/java/org/apache/fop/render/afp/AFPImageHandlerSVG.java index f38da91e9..5b30915b0 100644 --- a/fop-core/src/main/java/org/apache/fop/render/afp/AFPImageHandlerSVG.java +++ b/fop-core/src/main/java/org/apache/fop/render/afp/AFPImageHandlerSVG.java @@ -41,8 +41,7 @@ import org.apache.fop.afp.AFPGraphicsObjectInfo; import org.apache.fop.afp.AFPObjectAreaInfo; import org.apache.fop.afp.AFPPaintingState; import org.apache.fop.afp.AFPResourceInfo; -import org.apache.fop.afp.AFPResourceLevel; -import org.apache.fop.afp.AFPResourceLevel.ResourceType; +import org.apache.fop.afp.AFPResourceLevelDefaults; import org.apache.fop.afp.AFPResourceManager; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.image.loader.batik.BatikImageFlavors; @@ -81,8 +80,10 @@ public class AFPImageHandlerSVG implements ImageHandler { AFPDataObjectInfo info = createDataObjectInfo(); assert (info instanceof AFPGraphicsObjectInfo); AFPGraphicsObjectInfo graphicsObjectInfo = (AFPGraphicsObjectInfo) info; + graphicsObjectInfo.setCreatePageSegment(afpContext.getPaintingState().getWrapGocaPSeg()); AFPResourceInfo resourceInfo = graphicsObjectInfo.getResourceInfo(); - setDefaultToInlineResourceLevel(graphicsObjectInfo); + resourceInfo.setUri(imageSVG.getInfo().getOriginalURI()); + setDefaultToInlineResourceLevel(graphicsObjectInfo, afpContext.getResourceManager()); // Create a new AFPGraphics2D AFPPaintingState paintingState = afpContext.getPaintingState(); @@ -140,12 +141,12 @@ public class AFPImageHandlerSVG implements ImageHandler { paintingState.restore(); // resume } - private void setDefaultToInlineResourceLevel(AFPGraphicsObjectInfo graphicsObjectInfo) { + private void setDefaultToInlineResourceLevel(AFPGraphicsObjectInfo graphicsObjectInfo, + AFPResourceManager resourceManager) { AFPResourceInfo resourceInfo = graphicsObjectInfo.getResourceInfo(); - //level not explicitly set/changed so default to inline for GOCA graphic objects - // (due to a bug in the IBM AFP Workbench Viewer (2.04.01.07), hard copy works just fine) if (!resourceInfo.levelChanged()) { - resourceInfo.setLevel(new AFPResourceLevel(ResourceType.INLINE)); + resourceInfo.setLevel(resourceManager.getResourceLevelDefaults() + .getDefaultResourceLevel(AFPResourceLevelDefaults.TYPE_SVG)); } } diff --git a/fop-core/src/test/java/org/apache/fop/render/afp/AFPImageHandlerSVGTestCase.java b/fop-core/src/test/java/org/apache/fop/render/afp/AFPImageHandlerSVGTestCase.java new file mode 100644 index 000000000..61fb20730 --- /dev/null +++ b/fop-core/src/test/java/org/apache/fop/render/afp/AFPImageHandlerSVGTestCase.java @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.afp; + +import java.awt.Rectangle; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.util.Base64; +import java.util.HashMap; + +import org.junit.Assert; +import org.junit.Test; + +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import org.apache.commons.io.IOUtils; + +import org.apache.batik.anim.dom.SVGDOMImplementation; + +import org.apache.xmlgraphics.image.loader.ImageInfo; +import org.apache.xmlgraphics.image.loader.ImageSize; +import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; + +import org.apache.fop.afp.AFPPaintingState; +import org.apache.fop.afp.AFPResourceLevel; +import org.apache.fop.afp.AFPResourceManager; +import org.apache.fop.afp.modca.ResourceObject; +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.FopFactory; +import org.apache.fop.apps.io.InternalResourceResolver; +import org.apache.fop.apps.io.ResourceResolverFactory; +import org.apache.fop.image.loader.batik.BatikImageFlavors; + +public class AFPImageHandlerSVGTestCase { + + private Document createSVGDocument(float width, float height) throws IOException { + DOMImplementation impl = SVGDOMImplementation.getDOMImplementation(); + Document doc = impl.createDocument(SVGDOMImplementation.SVG_NAMESPACE_URI, "svg", null); + Element svgRoot = doc.getDocumentElement(); + svgRoot.setAttributeNS(null, "width", "" + width); + svgRoot.setAttributeNS(null, "height", "" + height); + Element e = doc.createElementNS(SVGDOMImplementation.SVG_NAMESPACE_URI, "svg:image"); + String img = Base64.getEncoder().encodeToString(IOUtils.toByteArray( + new FileInputStream("test/resources/images/cmyk.jpg"))); + e.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", "data:image/jpeg;base64," + img); + e.setAttribute("width", "1px"); + e.setAttribute("height", "1px"); + svgRoot.appendChild(e); + return doc; + } + + @Test + public void testAFPImageHandlerSVG() throws Exception { + String out = drawSVG(false); + Assert.assertEquals(out, "BEGIN RESOURCE_GROUP RG000001\n" + + "BEGIN NAME_RESOURCE RES00001 Triplets: OBJECT_FUNCTION_SET_SPECIFICATION,\n" + + "BEGIN IMAGE IMG00001\n" + + "BEGIN OBJECT_ENVIRONMENT_GROUP OEG00002\n" + + "DESCRIPTOR OBJECT_AREA Triplets: DESCRIPTOR_POSITION,MEASUREMENT_UNITS,OBJECT_AREA_SIZE,\n" + + "POSITION OBJECT_AREA\n" + + "MAP IMAGE Triplets: MAPPING_OPTION,\n" + + "DESCRIPTOR IMAGE\n" + + "END OBJECT_ENVIRONMENT_GROUP OEG00002\n" + + "DATA IMAGE\n" + + "END IMAGE IMG00001\n" + + "END NAME_RESOURCE RES00001\n"); + } + + private String drawSVG(boolean svgPrintFileLevel) throws Exception { + AFPImageHandlerSVG handler = new AFPImageHandlerSVG(); + FOUserAgent agent = FopFactory.newInstance(new URI(".")).newFOUserAgent(); + InternalResourceResolver resourceResolver = + ResourceResolverFactory.createDefaultInternalResourceResolver(new URI(".")); + AFPResourceManager manager = new AFPResourceManager(resourceResolver); + manager.getResourceLevelDefaults().setDefaultResourceLevel(ResourceObject.TYPE_GRAPHIC, + new AFPResourceLevel(AFPResourceLevel.ResourceType.PRINT_FILE)); + if (svgPrintFileLevel) { + manager.getResourceLevelDefaults().setDefaultResourceLevel("svg", + new AFPResourceLevel(AFPResourceLevel.ResourceType.PRINT_FILE)); + } + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + manager.createDataStream(null, stream).startPage(1, 1, 0, 1, 1); + AFPRenderingContext context = + new AFPRenderingContext(agent, manager, new AFPPaintingState(), null, new HashMap()); + context.getPaintingState().setWrapGocaPSeg(true); + Document doc = createSVGDocument(1, 2); + ImageInfo info = new ImageInfo("", ""); + info.setSize(new ImageSize()); + ImageXMLDOM img = new ImageXMLDOM(info, doc, BatikImageFlavors.SVG_DOM); + handler.handleImage(context, img, new Rectangle()); + StringBuilder sb = new StringBuilder(); + InputStream bis = new ByteArrayInputStream(stream.toByteArray()); + new AFPParser(false).read(bis, sb); + return sb.toString(); + } + + @Test + public void testAFPImageHandlerSVGResourceLevel() throws Exception { + String out = drawSVG(true); + Assert.assertEquals(out, "BEGIN RESOURCE_GROUP RG000001\n" + + "BEGIN NAME_RESOURCE RES00001 Triplets: OBJECT_FUNCTION_SET_SPECIFICATION,\n" + + "BEGIN IMAGE IMG00001\n" + + "BEGIN OBJECT_ENVIRONMENT_GROUP OEG00002\n" + + "DESCRIPTOR OBJECT_AREA Triplets: DESCRIPTOR_POSITION,MEASUREMENT_UNITS,OBJECT_AREA_SIZE,\n" + + "POSITION OBJECT_AREA\n" + + "MAP IMAGE Triplets: MAPPING_OPTION,\n" + + "DESCRIPTOR IMAGE\n" + + "END OBJECT_ENVIRONMENT_GROUP OEG00002\n" + + "DATA IMAGE\n" + + "END IMAGE IMG00001\n" + + "END NAME_RESOURCE RES00001\n" + + "BEGIN NAME_RESOURCE RES00002 Triplets: OBJECT_FUNCTION_SET_SPECIFICATION,\n" + + "BEGIN PAGE_SEGMENT S1000001\n" + + "BEGIN GRAPHICS S1000001\n" + + "BEGIN OBJECT_ENVIRONMENT_GROUP OEG00001\n" + + "DESCRIPTOR OBJECT_AREA Triplets: DESCRIPTOR_POSITION,MEASUREMENT_UNITS,OBJECT_AREA_SIZE,\n" + + "POSITION OBJECT_AREA\n" + + "DESCRIPTOR GRAPHICS\n" + + "END OBJECT_ENVIRONMENT_GROUP OEG00001\n" + + "END GRAPHICS S1000001\n" + + "END PAGE_SEGMENT S1000001\n" + + "END NAME_RESOURCE RES00002\n"); + } +} diff --git a/fop-core/src/test/java/org/apache/fop/render/afp/AFPRendererConfiguratorTestCase.java b/fop-core/src/test/java/org/apache/fop/render/afp/AFPRendererConfiguratorTestCase.java index 817d7ab0c..a47326599 100644 --- a/fop-core/src/test/java/org/apache/fop/render/afp/AFPRendererConfiguratorTestCase.java +++ b/fop-core/src/test/java/org/apache/fop/render/afp/AFPRendererConfiguratorTestCase.java @@ -21,6 +21,7 @@ import java.net.URI; import java.util.HashMap; import java.util.Map; +import org.junit.Assert; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -189,6 +190,19 @@ public class AFPRendererConfiguratorTestCase extends testResourceLevelDefault(ResourceType.PRINT_FILE); } + @Test + public void testSVGResourceLevel() throws Exception { + Map resourceLevels = new HashMap<>(); + resourceLevels.put("svg", ResourceType.PRINT_FILE.getName()); + parseConfig(createBuilder().setDefaultResourceLevels(resourceLevels)); + ArgumentCaptor argument = ArgumentCaptor.forClass(AFPResourceLevelDefaults.class); + verify(getDocHandler()).setResourceLevelDefaults(argument.capture()); + assertEquals(new AFPResourceLevel(ResourceType.PRINT_FILE), + argument.getValue().getDefaultResourceLevel(AFPResourceLevelDefaults.TYPE_SVG)); + Assert.assertTrue( + new AFPResourceLevelDefaults().getDefaultResourceLevel(AFPResourceLevelDefaults.TYPE_SVG).isInline()); + } + @Test public void testBitmapEncodeQuality() throws Exception { parseConfig(createBuilder().startImages()