]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
FOP-3184: Allow change of resource level for SVG in AFP
authorSimon Steiner <ssteiner@apache.org>
Thu, 6 Jun 2024 15:09:34 +0000 (16:09 +0100)
committerSimon Steiner <ssteiner@apache.org>
Thu, 6 Jun 2024 15:09:34 +0000 (16:09 +0100)
fop-core/src/main/java/org/apache/fop/afp/AFPResourceLevelDefaults.java
fop-core/src/main/java/org/apache/fop/render/afp/AFPImageHandlerSVG.java
fop-core/src/test/java/org/apache/fop/render/afp/AFPImageHandlerSVGTestCase.java [new file with mode: 0644]
fop-core/src/test/java/org/apache/fop/render/afp/AFPRendererConfiguratorTestCase.java

index f1df49b62697a41c400b888fa1c01eb4b7afe3fe..381d0a7ad67e49dcb9c552da071893ab064f68f1 100644 (file)
@@ -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));
     }
 
     /**
index f38da91e972df1c54af5dcbccfb2544cb16e6814..5b30915b0f10379407f08c79aac404856f3f9da5 100644 (file)
@@ -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 (file)
index 0000000..61fb207
--- /dev/null
@@ -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");
+    }
+}
index 817d7ab0cc5fc10ecee633372114c7ba18bbd02a..a47326599e538502b12091c009819ea904a3d869 100644 (file)
@@ -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<String, String> resourceLevels = new HashMap<>();
+        resourceLevels.put("svg", ResourceType.PRINT_FILE.getName());
+        parseConfig(createBuilder().setDefaultResourceLevels(resourceLevels));
+        ArgumentCaptor<AFPResourceLevelDefaults> 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()