svn commit: r1903806 - in /xmlgraphics/fop/trunk/fop-core/src: main/java/org/apache/fop/afp/ main/java/org/apache/fop/afp/ioca/ main/java/org/apache/fop/afp/modca/ main/java/org/apache/fop/render/afp/ test/java/org/apache/fop/afp/ test/java/org/apache/...

[email protected] Thu, 01 Sep 2022 10:14:56 -0000
Newsgroups gmane.text.xml.fop.cvs
Message-ID <[email protected]>
Author: ssteiner
Date: Thu Sep  1 10:14:56 2022
New Revision: 1903806

URL: http://svn.apache.org/viewvc?rev=1903806&view=rev
Log:
FOP-3091: Add transparency color support for AFP

Added:
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/TransparencyMask.java   (with props)
    xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/afp/AFPRectanglePainterTestCase.java   (with props)
    xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/afp/ioca/
    xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/afp/ioca/ImageContentTestCase.java   (with props)
Modified:
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/AFPDataObjectFactory.java
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/AFPDataObjectInfo.java
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/AFPRectanglePainter.java
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/ImageContent.java
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/ImageSegment.java
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/Tile.java
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/modca/ImageObject.java
    xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/render/afp/AFPDocumentHandler.java

Modified: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/AFPDataObjectFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/AFPDataObjectFactory.java?rev=1903806&r1=1903805&r2=1903806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/AFPDataObjectFactory.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/AFPDataObjectFactory.java Thu Sep  1 10:14:56 2022
@@ -150,6 +150,7 @@ public class AFPDataObjectFactory {
         }
 
         imageObj.setData(imageObjectInfo.getData());
+        imageObj.setTransparencyMask(imageObjectInfo.getTransparencyMask());
 
         return imageObj;
     }

Modified: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/AFPDataObjectInfo.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/AFPDataObjectInfo.java?rev=1903806&r1=1903805&r2=1903806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/AFPDataObjectInfo.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/AFPDataObjectInfo.java Thu Sep  1 10:14:56 2022
@@ -45,6 +45,8 @@ public class AFPDataObjectInfo {
     /** the object data in a byte array */
     private byte[] data;
 
+    private byte[] transparencyMask;
+
     /** the object data height resolution */
     private int dataHeightRes;
 
@@ -239,6 +241,14 @@ public class AFPDataObjectInfo {
         return this.data;
     }
 
+    public void setTransparencyMask(byte[] transparencyMask) {
+        this.transparencyMask = transparencyMask;
+    }
+
+    public byte[] getTransparencyMask() {
+        return transparencyMask;
+    }
+
     /**
      * Controls whether to create a page segment or a normal object.
      * @param value true for page segments, false for objects

Modified: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/AFPRectanglePainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/AFPRectanglePainter.java?rev=1903806&r1=1903805&r2=1903806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/AFPRectanglePainter.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/AFPRectanglePainter.java Thu Sep  1 10:14:56 2022
@@ -19,26 +19,50 @@
 
 package org.apache.fop.afp;
 
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
 import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferByte;
+import java.awt.image.RenderedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.apache.xmlgraphics.image.loader.ImageSize;
+import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives;
+import org.apache.xmlgraphics.util.MimeConstants;
 
+import org.apache.fop.util.bitmap.BitmapImageUtil;
 
 /**
  * A painter of rectangles in AFP
  */
 public class AFPRectanglePainter extends AbstractAFPPainter {
 
+    private AFPResourceManager resourceManager;
+
     /**
      * Main constructor
      *
      * @param paintingState the AFP painting state
      * @param dataStream the AFP datastream
      */
-    public AFPRectanglePainter(AFPPaintingState paintingState, DataStream dataStream) {
+    public AFPRectanglePainter(AFPPaintingState paintingState, DataStream dataStream,
+                               AFPResourceManager resourceManager) {
         super(paintingState, dataStream);
+        this.resourceManager = resourceManager;
     }
 
     /** {@inheritDoc} */
-    public void paint(PaintingInfo paintInfo) {
+    public void paint(PaintingInfo paintInfo) throws IOException {
+        Color color = paintingState.getColor();
+        if (color instanceof ColorWithAlternatives && color.getAlpha() != 255) {
+            paintAlpha(paintInfo);
+            return;
+        }
+
         RectanglePaintingInfo rectanglePaintInfo = (RectanglePaintingInfo)paintInfo;
         int pageWidth = dataStream.getCurrentPage().getWidth();
         int pageHeight = dataStream.getCurrentPage().getHeight();
@@ -90,4 +114,87 @@ public class AFPRectanglePainter extends
         }
         dataStream.createLine(lineDataInfo);
     }
+
+    private void paintAlpha(PaintingInfo paintInfo) throws IOException {
+        RectanglePaintingInfo rectanglePaintInfo = (RectanglePaintingInfo)paintInfo;
+        if (rectanglePaintInfo.getWidth() <= 0 || rectanglePaintInfo.getHeight() <= 0) {
+            return;
+        }
+        Dimension size = new Dimension((int)rectanglePaintInfo.getWidth(), (int)rectanglePaintInfo.getHeight());
+
+        AFPImageObjectInfo imageObjectInfo = new AFPImageObjectInfo();
+        imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS45);
+        imageObjectInfo.getResourceInfo().setLevel(new AFPResourceLevel(AFPResourceLevel.ResourceType.INLINE));
+        imageObjectInfo.getResourceInfo().setImageDimension(size);
+        imageObjectInfo.setColor(true);
+
+        int width = size.width;
+        int height = size.height;
+        int resolution = paintingState.getResolution();
+        ImageSize bitmapSize = new ImageSize(width, height, resolution);
+        imageObjectInfo.setDataHeightRes((int)Math.round(bitmapSize.getDpiHorizontal() * 10));
+        imageObjectInfo.setDataWidthRes((int)Math.round(bitmapSize.getDpiVertical() * 10));
+        imageObjectInfo.setDataWidth(width);
+        imageObjectInfo.setDataHeight(height);
+
+        Color color = paintingState.getColor();
+        byte[] image = buildImage(color, width, height);
+        imageObjectInfo.setData(image);
+        if (color instanceof ColorWithAlternatives) {
+            imageObjectInfo.setBitsPerPixel(32);
+        } else {
+            imageObjectInfo.setBitsPerPixel(24);
+        }
+
+        image = buildMaskImage(color, width, height);
+        imageObjectInfo.setTransparencyMask(image);
+
+        int rotation = paintingState.getRotation();
+        AffineTransform at = paintingState.getData().getTransform();
+        Point2D origin = at.transform(new Point2D.Float(
+                rectanglePaintInfo.getX() * 1000,
+                rectanglePaintInfo.getY() * 1000), null);
+        AFPUnitConverter unitConv = paintingState.getUnitConverter();
+        float widthf = unitConv.pt2units(rectanglePaintInfo.getWidth());
+        float heightf = unitConv.pt2units(rectanglePaintInfo.getHeight());
+        AFPObjectAreaInfo objectAreaInfo = new AFPObjectAreaInfo(
+                (int) Math.round(origin.getX()),
+                (int) Math.round(origin.getY()),
+                Math.round(widthf), Math.round(heightf), resolution, rotation);
+        imageObjectInfo.setObjectAreaInfo(objectAreaInfo);
+
+        resourceManager.createObject(imageObjectInfo);
+    }
+
+    private byte[] buildImage(Color color, int width, int height) {
+        float[] components;
+        if (color instanceof ColorWithAlternatives) {
+            components = ((ColorWithAlternatives)color).getAlternativeColors()[0].getColorComponents(null);
+        } else {
+            components = color.getColorComponents(null);
+        }
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        for (int y = 0; y < height; y++) {
+            for (int x = 0; x < width; x++) {
+                for (float component : components) {
+                    component *= 255;
+                    bos.write((byte)component);
+                }
+            }
+        }
+        return bos.toByteArray();
+    }
+
+    private byte[] buildMaskImage(Color color, int width, int height) {
+        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+        Graphics graphics = bufferedImage.getGraphics();
+        Color alpha = new Color(color.getAlpha(), color.getAlpha(), color.getAlpha());
+        graphics.setColor(alpha);
+        graphics.fillRect(0, 0, width, height);
+        graphics.dispose();
+        RenderedImage renderedImage =
+                BitmapImageUtil.convertToMonochrome(bufferedImage, new Dimension(width, height), 1);
+        DataBufferByte bufferByte = (DataBufferByte) renderedImage.getData().getDataBuffer();
+        return bufferByte.getData();
+    }
 }

Modified: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/ImageContent.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/ImageContent.java?rev=1903806&r1=1903805&r2=1903806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/ImageContent.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/ImageContent.java Thu Sep  1 10:14:56 2022
@@ -182,12 +182,18 @@ public class ImageContent extends Abstra
         }
     }
 
-    private static final int MAX_DATA_LEN = 65535;
+    public void setTransparencyMask(byte[] transparencyMask) {
+        if (transparencyMask != null) {
+            tile.setTransparencyMask(new TransparencyMask(transparencyMask, imageSizeParameter));
+        }
+    }
+
+    private static final int MAX_DATA_LEN = 8188;
 
     /** {@inheritDoc} */
     @Override
     protected void writeContent(OutputStream os) throws IOException {
-        if (imageSizeParameter != null) {
+        if (imageSizeParameter != null && tile == null) {
             imageSizeParameter.writeToStream(os);
         }
 

Modified: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/ImageSegment.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/ImageSegment.java?rev=1903806&r1=1903805&r2=1903806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/ImageSegment.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/ImageSegment.java Thu Sep  1 10:14:56 2022
@@ -136,6 +136,10 @@ public class ImageSegment extends Abstra
         getImageContent().setImageData(imageData);
     }
 
+    public void setTransparencyMask(byte[] transparencyMask) {
+        getImageContent().setTransparencyMask(transparencyMask);
+    }
+
     /** {@inheritDoc} */
     public void writeContent(OutputStream os) throws IOException {
         if (imageContent != null) {

Modified: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/Tile.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/Tile.java?rev=1903806&r1=1903805&r2=1903806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/Tile.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/Tile.java Thu Sep  1 10:14:56 2022
@@ -31,6 +31,7 @@ public class Tile extends AbstractStruct
     private TilePosition tilePosition;
     private TileSize tileSize;
     private BandImage bandImage;
+    private TransparencyMask transparencyMask;
     private byte[] data;
 
     private IDEStructureParameter ideStructureParameter;
@@ -50,7 +51,40 @@ public class Tile extends AbstractStruct
         if (ideStructureParameter != null) {
             ideStructureParameter.writeToStream(os);
         }
+        if (transparencyMask != null) {
+            transparencyMask.writeToStream(os);
+        }
         if (data != null) {
+            writeData(os);
+        }
+    }
+
+    private void writeData(OutputStream os) throws IOException {
+        final byte[] dataHeader = new byte[]{(byte) 0xFE, // ID
+                (byte) 0x9C, // ID
+                0x00, // length
+                0x00, // length
+                0x00, // bandnum
+                0x00, // reserved
+                0x00 // reserved
+        };
+        final int lengthOffset = 2;
+        if (ideSize == 24) {
+            byte[] red = new byte[data.length / 3];
+            byte[] green = new byte[data.length / 3];
+            byte[] blue = new byte[data.length / 3];
+            for (int j = 0; j < data.length / 3; j++) {
+                red[j] = data[3 * j];
+                green[j] = data[3 * j + 1];
+                blue[j] = data[3 * j + 2];
+            }
+            dataHeader[4] = (byte) 0x01;
+            writeChunksToStream(red, dataHeader, lengthOffset, MAX_DATA_LEN, os);
+            dataHeader[4] = (byte) 0x02;
+            writeChunksToStream(green, dataHeader, lengthOffset, MAX_DATA_LEN, os);
+            dataHeader[4] = (byte) 0x03;
+            writeChunksToStream(blue, dataHeader, lengthOffset, MAX_DATA_LEN, os);
+        } else {
             byte[] c = new byte[data.length / 4];
             byte[] m = new byte[data.length / 4];
             byte[] y = new byte[data.length / 4];
@@ -61,15 +95,6 @@ public class Tile extends AbstractStruct
                 y[j] = data[4 * j + 2];
                 k[j] = data[4 * j + 3];
             }
-            final byte[] dataHeader = new byte[] {(byte) 0xFE, // ID
-                    (byte) 0x9C, // ID
-                    0x00, // length
-                    0x00, // length
-                    0x00, // bandnum
-                    0x00, // reserved
-                    0x00 // reserved
-            };
-            final int lengthOffset = 2;
             dataHeader[4] = (byte) 0x01;
             writeChunksToStream(c, dataHeader, lengthOffset, MAX_DATA_LEN, os);
             dataHeader[4] = (byte) 0x02;
@@ -116,7 +141,7 @@ public class Tile extends AbstractStruct
         int numFullChunks = dataLength / maxChunkLength;
         int lastChunkLength = dataLength % maxChunkLength;
 
-        byte[] len = {(byte) 0x1f, (byte) 0xff};
+        byte[] len = BinaryUtils.convert(3 + maxChunkLength, 2);
         int off = 0;
         if (numFullChunks > 0) {
             // write out full data chunks
@@ -173,4 +198,7 @@ public class Tile extends AbstractStruct
         this.bandImage = bandImage;
     }
 
+    public void setTransparencyMask(TransparencyMask transparencyMask) {
+        this.transparencyMask = transparencyMask;
+    }
 }

Added: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/TransparencyMask.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/TransparencyMask.java?rev=1903806&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/TransparencyMask.java (added)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/TransparencyMask.java Thu Sep  1 10:14:56 2022
@@ -0,0 +1,62 @@
+/*
+ * 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.afp.ioca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.fop.afp.modca.AbstractAFPObject;
+
+public class TransparencyMask extends AbstractAFPObject {
+    private static final int MAX_DATA_LEN = 8188;
+    private ImageSizeParameter imageSizeParameter;
+    private byte[] maskData;
+
+    public TransparencyMask(byte[] maskData, ImageSizeParameter imageSizeParameter) {
+        this.maskData = maskData;
+        this.imageSizeParameter = imageSizeParameter;
+    }
+
+    public void writeToStream(OutputStream os) throws IOException {
+        os.write(0x8E);
+        os.write(0);
+        imageSizeParameter.writeToStream(os);
+        os.write(getImageEncodingParameter());
+
+        final byte[] dataHeader = new byte[] {(byte) 0xFE, // ID
+                (byte) 0x92, // ID
+                0x00, // length
+                0x00 // length
+        };
+        final int lengthOffset = 2;
+        writeChunksToStream(maskData, dataHeader, lengthOffset, MAX_DATA_LEN, os);
+
+        os.write(0x8F);
+        os.write(0);
+    }
+
+    private byte[] getImageEncodingParameter() {
+        byte encoding = (byte) 0x03;
+        return new byte[] {(byte) 0x95, // ID
+                0x02, // Length
+                encoding,
+                (byte) 0x01, // RECID
+        };
+    }
+}

Propchange: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/ioca/TransparencyMask.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/modca/ImageObject.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/modca/ImageObject.java?rev=1903806&r1=1903805&r2=1903806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/modca/ImageObject.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/afp/modca/ImageObject.java Thu Sep  1 10:14:56 2022
@@ -79,11 +79,9 @@ public class ImageObject extends Abstrac
         ImageDataDescriptor imageDataDescriptor
             = factory.createImageDataDescriptor(dataWidth, dataHeight, dataWidthRes, dataHeightRes);
 
-        boolean setImageSize = true;
         if (MimeConstants.MIME_AFP_IOCA_FS45.equals(imageObjectInfo.getMimeType())) {
             imageDataDescriptor.setFunctionSet(ImageDataDescriptor.FUNCTION_SET_FS45);
             if (imageObjectInfo.getBitsPerPixel() == 32) {
-                 setImageSize = false;
                  Tile tile = factory.createTile();
                  TilePosition tilePosition = factory.createTilePosition();
                  TileSize tileSize = factory.createTileSize(dataWidth, dataHeight, dataWidthRes, dataHeightRes);
@@ -101,10 +99,8 @@ public class ImageObject extends Abstrac
         getObjectEnvironmentGroup().setMapImageObject(
                 new MapImageObject(dataObjectInfo.getMappingOption()));
 
-        if (setImageSize) {
-            // not used for FS45
-            getImageSegment().setImageSize(dataWidth, dataHeight, dataWidthRes, dataHeightRes);
-        }
+        // not used for FS45
+        getImageSegment().setImageSize(dataWidth, dataHeight, dataWidthRes, dataHeightRes);
     }
 
     /**
@@ -164,6 +160,10 @@ public class ImageObject extends Abstrac
         getImageSegment().setData(imageData);
     }
 
+    public void setTransparencyMask(byte[] date) {
+        getImageSegment().setTransparencyMask(date);
+    }
+
     /** {@inheritDoc} */
     protected void writeStart(OutputStream os) throws IOException {
         byte[] data = new byte[17];

Modified: xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/render/afp/AFPDocumentHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/render/afp/AFPDocumentHandler.java?rev=1903806&r1=1903805&r2=1903806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/render/afp/AFPDocumentHandler.java (original)
+++ xmlgraphics/fop/trunk/fop-core/src/main/java/org/apache/fop/render/afp/AFPDocumentHandler.java Thu Sep  1 10:14:56 2022
@@ -164,7 +164,7 @@ public class AFPDocumentHandler extends
                     getPaintingState(), getDataStream(), getResourceManager());
         } else {
             return new AFPRectanglePainter(
-                    getPaintingState(), getDataStream());
+                    getPaintingState(), getDataStream(), getResourceManager());
         }
     }
 

Added: xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/afp/AFPRectanglePainterTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/afp/AFPRectanglePainterTestCase.java?rev=1903806&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/afp/AFPRectanglePainterTestCase.java (added)
+++ xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/afp/AFPRectanglePainterTestCase.java Thu Sep  1 10:14:56 2022
@@ -0,0 +1,83 @@
+/*
+ * 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.afp;
+
+import java.awt.Color;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.xmlgraphics.java2d.color.ColorSpaces;
+import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives;
+
+import org.apache.fop.afp.parser.MODCAParser;
+import org.apache.fop.afp.parser.UnparsedStructuredField;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.FopFactory;
+
+public class AFPRectanglePainterTestCase {
+    @Test
+    public void testCMYKTransparencyMask() throws Exception {
+        float cyan = 0.5f;
+        Color deviceColor = new Color(ColorSpaces.getDeviceCMYKColorSpace(), new float[]{cyan, 0, 0, 0}, 0.4f);
+        ByteArrayInputStream bis = buildAFP(new ColorWithAlternatives(0, 0, 0, 128, new Color[]{deviceColor}));
+        bis.skip(59);
+        Assert.assertEquals(bis.read(), 0x8E); //start
+        bis.skip(20);
+        Assert.assertEquals(bis.read(), 170); //mask data
+        bis.skip(1299);
+        Assert.assertEquals(bis.read(), 0x8F); //end
+        bis.skip(89);
+        Assert.assertEquals(bis.read(), 127); //cyan byte
+    }
+
+    @Test
+    public void testRGBTransparencyMask() throws Exception {
+        ByteArrayInputStream bis = buildAFP(new Color(0, 0, 0, 128));
+        Assert.assertNull(bis);
+    }
+
+    private ByteArrayInputStream buildAFP(Color color) throws Exception {
+        FOUserAgent foUserAgent = FopFactory.newInstance(new File(".").toURI()).newFOUserAgent();
+        AFPPaintingState paintingState = new AFPPaintingState();
+        paintingState.setColor(color);
+        AFPResourceManager resourceManager = new AFPResourceManager(foUserAgent.getResourceResolver());
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        DataStream stream = resourceManager.createDataStream(paintingState, bos);
+        stream.startDocument();
+        stream.startPage(100, 100, 0, 10, 10);
+        AFPRectanglePainter painter = new AFPRectanglePainter(paintingState, stream, resourceManager);
+        painter.paint(new RectanglePaintingInfo(0, 0, 100, 100));
+        stream.endPage();
+        stream.endDocument();
+        resourceManager.writeToStream();
+
+        MODCAParser parser = new MODCAParser(new ByteArrayInputStream(bos.toByteArray()));
+        UnparsedStructuredField structuredField;
+        while ((structuredField = parser.readNextStructuredField()) != null) {
+            if (structuredField.toString().endsWith("Data Image")) {
+                return new ByteArrayInputStream(structuredField.getData());
+            }
+        }
+        return null;
+    }
+}

Propchange: xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/afp/AFPRectanglePainterTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/afp/ioca/ImageContentTestCase.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/afp/ioca/ImageContentTestCase.java?rev=1903806&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/afp/ioca/ImageContentTestCase.java (added)
+++ xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/afp/ioca/ImageContentTestCase.java Thu Sep  1 10:14:56 2022
@@ -0,0 +1,48 @@
+/*
+ * 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.afp.ioca;
+
+import java.io.ByteArrayOutputStream;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ImageContentTestCase {
+    @Test
+    public void testImageSizeParameterWritten() throws Exception {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ImageContent imageContent = new ImageContent();
+        imageContent.setImageSizeParameter(new ImageSizeParameter(1, 1, 1, 1));
+        imageContent.writeToStream(bos);
+        Assert.assertEquals(bos.size(), 20);
+    }
+
+    @Test
+    public void testImageSizeParameterNotWritten() throws Exception {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ImageContent imageContent = new ImageContent();
+        imageContent.setImageSizeParameter(new ImageSizeParameter(1, 1, 1, 1));
+        Tile tile = new Tile();
+        tile.setPosition(new TilePosition());
+        tile.setSize(new TileSize(1, 1, 1, 1));
+        imageContent.addTile(tile);
+        imageContent.writeToStream(bos);
+        Assert.assertEquals(bos.size(), 34);
+    }
+}

Propchange: xmlgraphics/fop/trunk/fop-core/src/test/java/org/apache/fop/afp/ioca/ImageContentTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native