Author: vhennebert
Date: Tue Apr 28 16:10:08 2009
New Revision: 769445

URL: http://svn.apache.org/viewvc?rev=769445&view=rev
Log:
Added setting to enable dithered painting of filled rectangles in AFP and PCL.

Added:
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPDitheredRectanglePainter.java
   (with props)
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPShadingMode.java   
(with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/util/bitmap/DitherUtil.java   
(with props)
Modified:
    xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/output.xml
    xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPDataObjectInfo.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AbstractAFPPainter.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/ImageObject.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/triplets/MappingOptionTriplet.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPCustomizable.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPPainter.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPRenderer.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLGenerator.java
    xmlgraphics/fop/trunk/status.xml

Modified: xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/output.xml
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/output.xml?rev=769445&r1=769444&r2=769445&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/output.xml 
(original)
+++ xmlgraphics/fop/trunk/src/documentation/content/xdocs/trunk/output.xml Tue 
Apr 28 16:10:08 2009
@@ -680,6 +680,20 @@
       Support for native image formats (e.g. JPEG, GIF) is not always 
available on printer implementations
       so by default this configuration option is set to "false".</p>
       </section>
+      <section id="afp-shading-config">
+        <title>Shading</title>
+        <p>
+          By default, filled rectangles are painted using their given color 
using a PTOCA I-axis rule
+          (DIR). But not all environments handle these colors correctly. 
That's why a setting is
+          supported that paints the rectangles using an ordered dither pattern 
(bi-level) with
+          an inline IOCA FS10 image that is used together with the "replicate 
and trim" mapping.
+          The optional "shading" element can be used to control the shading 
mode. Its default value
+          is "color". To enable the dithered mode, use "dithered". Example: 
+        </p>
+      <source><![CDATA[
+      <shading>dithered</shading>
+]]></source>
+      </section>
       <section id="afp-resource-group-file">
       <title>Resource Group File</title>
       <p>By default the AFP Renderer will place all data resource objects such 
as images within

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPDataObjectInfo.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPDataObjectInfo.java?rev=769445&r1=769444&r2=769445&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPDataObjectInfo.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPDataObjectInfo.java 
Tue Apr 28 16:10:08 2009
@@ -23,6 +23,7 @@
 import org.apache.commons.logging.LogFactory;
 
 import org.apache.fop.afp.modca.Registry;
+import org.apache.fop.afp.modca.triplets.MappingOptionTriplet;
 
 /**
  * A list of parameters associated with an AFP data objects
@@ -57,6 +58,9 @@
     /** controls whether to create a page segment or a simple object */
     private boolean createPageSegment;
 
+    /** controls the mapping of the image data into the image area */
+    private byte mappingOption = MappingOptionTriplet.SCALE_TO_FILL;
+
     /**
      * Default constructor
      */
@@ -253,6 +257,23 @@
         return this.createPageSegment;
     }
 
+    /**
+     * Sets the way an image is mapped into its target area.
+     * @param mappingOption the mapping option (Valid values: see Mapping 
Option Triplet)
+     */
+    public void setMappingOption(byte mappingOption) {
+        this.mappingOption = mappingOption;
+    }
+
+    /**
+     * Returns the way an image is mapped into its target area. By default, 
this is "scale to fill"
+     * behavior.
+     * @return the mapping option value from the Mapping Option Triplet
+     */
+    public byte getMappingOption() {
+        return mappingOption;
+    }
+
     /** {...@inheritdoc} */
     public String toString() {
         return "AFPDataObjectInfo{"
@@ -264,4 +285,5 @@
             + (objectAreaInfo != null ? ", objectAreaInfo=" + objectAreaInfo : 
"")
             + (resourceInfo != null ? ", resourceInfo=" + resourceInfo : "");
     }
+
 }

Added: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPDitheredRectanglePainter.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPDitheredRectanglePainter.java?rev=769445&view=auto
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPDitheredRectanglePainter.java
 (added)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPDitheredRectanglePainter.java
 Tue Apr 28 16:10:08 2009
@@ -0,0 +1,112 @@
+/*
+ * 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.awt.Dimension;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.io.IOException;
+
+import org.apache.xmlgraphics.image.loader.ImageSize;
+import org.apache.xmlgraphics.util.MimeConstants;
+
+import org.apache.fop.afp.modca.triplets.MappingOptionTriplet;
+import org.apache.fop.util.bitmap.DitherUtil;
+
+
+/**
+ * A painter of rectangles in AFP
+ */
+public class AFPDitheredRectanglePainter extends AbstractAFPPainter {
+
+    private AFPResourceManager resourceManager;
+
+    /**
+     * Main constructor
+     *
+     * @param paintingState the AFP painting state
+     * @param dataStream the AFP datastream
+     * @param resourceManager the resource manager
+     */
+    public AFPDitheredRectanglePainter(AFPPaintingState paintingState, 
DataStream dataStream,
+            AFPResourceManager resourceManager) {
+        super(paintingState, dataStream);
+        this.resourceManager = resourceManager;
+    }
+
+    /** {...@inheritdoc} */
+    public void paint(PaintingInfo paintInfo) throws IOException {
+        RectanglePaintingInfo rectanglePaintInfo = 
(RectanglePaintingInfo)paintInfo;
+
+        int ditherMatrix = DitherUtil.DITHER_MATRIX_8X8;
+        Dimension ditherSize = new Dimension(ditherMatrix, ditherMatrix);
+
+        //Prepare an FS10 bi-level image
+        AFPImageObjectInfo imageObjectInfo = new AFPImageObjectInfo();
+        imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS10);
+        //imageObjectInfo.setCreatePageSegment(true);
+        imageObjectInfo.getResourceInfo().setLevel(new 
AFPResourceLevel(AFPResourceLevel.INLINE));
+        imageObjectInfo.getResourceInfo().setImageDimension(ditherSize);
+        imageObjectInfo.setBitsPerPixel(1);
+        imageObjectInfo.setColor(false);
+        //Note: the following may not be supported by older implementations
+        
imageObjectInfo.setMappingOption(MappingOptionTriplet.REPLICATE_AND_TRIM);
+
+        //Dither image size
+        int resolution = paintingState.getResolution();
+        ImageSize ditherBitmapSize = new ImageSize(
+                ditherSize.width, ditherSize.height, resolution);
+        imageObjectInfo.setDataHeightRes((int)Math.round(
+                ditherBitmapSize.getDpiHorizontal() * 10));
+        imageObjectInfo.setDataWidthRes((int)Math.round(
+                ditherBitmapSize.getDpiVertical() * 10));
+        imageObjectInfo.setDataWidth(ditherSize.width);
+        imageObjectInfo.setDataHeight(ditherSize.height);
+
+        //Create dither image
+        Color col = paintingState.getColor();
+        byte[] dither = DitherUtil.getBayerDither(ditherMatrix, col, false);
+        imageObjectInfo.setData(dither);
+
+        //Positioning
+        AFPObjectAreaInfo objectAreaInfo = new AFPObjectAreaInfo();
+        int rotation = paintingState.getRotation();
+        AffineTransform at = paintingState.getData().getTransform();
+        Point2D origin = at.transform(new Point2D.Float(
+                rectanglePaintInfo.getX() * 1000,
+                rectanglePaintInfo.getY() * 1000), null);
+        objectAreaInfo.setX((int)Math.round(origin.getX()));
+        objectAreaInfo.setY((int)Math.round(origin.getY()));
+        AFPUnitConverter unitConv = paintingState.getUnitConverter();
+        float width = unitConv.pt2units(rectanglePaintInfo.getWidth());
+        float height = unitConv.pt2units(rectanglePaintInfo.getHeight());
+        objectAreaInfo.setWidth(Math.round(width));
+        objectAreaInfo.setHeight(Math.round(height));
+        objectAreaInfo.setHeightRes(resolution);
+        objectAreaInfo.setWidthRes(resolution);
+        objectAreaInfo.setRotation(rotation);
+        imageObjectInfo.setObjectAreaInfo(objectAreaInfo);
+
+        //Create rectangle
+        resourceManager.createObject(imageObjectInfo);
+    }
+
+}

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

Propchange: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AFPDitheredRectanglePainter.java
------------------------------------------------------------------------------
    svn:keywords = Revision Id

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AbstractAFPPainter.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AbstractAFPPainter.java?rev=769445&r1=769444&r2=769445&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AbstractAFPPainter.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/AbstractAFPPainter.java 
Tue Apr 28 16:10:08 2009
@@ -19,6 +19,8 @@
 
 package org.apache.fop.afp;
 
+import java.io.IOException;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -48,6 +50,7 @@
      * Paints the painting item
      *
      * @param paintInfo the painting information
+     * @throws IOException if an I/O error occurs
      */
-    public abstract void paint(PaintingInfo paintInfo);
+    public abstract void paint(PaintingInfo paintInfo) throws IOException;
 }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/ImageObject.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/ImageObject.java?rev=769445&r1=769444&r2=769445&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/ImageObject.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/ImageObject.java 
Tue Apr 28 16:10:08 2009
@@ -28,7 +28,6 @@
 import org.apache.fop.afp.AFPImageObjectInfo;
 import org.apache.fop.afp.Factory;
 import org.apache.fop.afp.ioca.ImageSegment;
-import org.apache.fop.afp.modca.triplets.MappingOptionTriplet;
 
 /**
  * An IOCA Image Data Object
@@ -66,10 +65,6 @@
         int dataWidth = imageObjectInfo.getDataWidth();
         int dataHeight = imageObjectInfo.getDataHeight();
 
-//        AFPObjectAreaInfo objectAreaInfo = 
dataObjectInfo.getObjectAreaInfo();
-//        int widthRes = objectAreaInfo.getWidthRes();
-//        int heightRes = objectAreaInfo.getHeightRes();
-
         int dataWidthRes = imageObjectInfo.getDataWidthRes();
         int dataHeightRes = imageObjectInfo.getDataWidthRes();
         ImageDataDescriptor imageDataDescriptor
@@ -79,7 +74,7 @@
         }
         getObjectEnvironmentGroup().setDataDescriptor(imageDataDescriptor);
         getObjectEnvironmentGroup().setMapImageObject(
-                new MapImageObject(MappingOptionTriplet.SCALE_TO_FILL));
+                new MapImageObject(dataObjectInfo.getMappingOption()));
 
         getImageSegment().setImageSize(dataWidth, dataHeight, dataWidthRes, 
dataHeightRes);
     }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/triplets/MappingOptionTriplet.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/triplets/MappingOptionTriplet.java?rev=769445&r1=769444&r2=769445&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/triplets/MappingOptionTriplet.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/triplets/MappingOptionTriplet.java
 Tue Apr 28 16:10:08 2009
@@ -50,9 +50,14 @@
      */
     public static final byte CENTER_AND_TRIM = 0x30;
 
-//    public static final byte MIGRATION_MAPPING_1 = 0x41;
-//    public static final byte MIGRATION_MAPPING_2 = 0x42;
-//    public static final byte MIGRATION_MAPPING_3 = 0x50;
+    /** Migration mapping option: Image point-to-pel. */
+    public static final byte IMAGE_POINT_TO_PEL = 0x41;
+
+    /** Migration mapping option: Image point-to-pel with double dot. */
+    public static final byte IMAGE_POINT_TO_PEL_DOUBLE_DOT = 0x42;
+
+    /** Migration mapping option: Replicate and trim. */
+    public static final byte REPLICATE_AND_TRIM = 0x50;
 
     /** the data object is centred, aspect ratio is not always preserved */
     public static final byte SCALE_TO_FILL = 0x60;

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPCustomizable.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPCustomizable.java?rev=769445&r1=769444&r2=769445&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPCustomizable.java 
(original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPCustomizable.java 
Tue Apr 28 16:10:08 2009
@@ -51,6 +51,12 @@
     void setNativeImagesSupported(boolean nativeImages);
 
     /**
+     * Sets the shading mode for painting filled rectangles.
+     * @param shadingMode the shading mode
+     */
+    void setShadingMode(AFPShadingMode shadingMode);
+
+    /**
      * Sets the output/device resolution
      *
      * @param resolution

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java?rev=769445&r1=769444&r2=769445&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
 Tue Apr 28 16:10:08 2009
@@ -25,10 +25,13 @@
 import java.io.IOException;
 import java.util.Map;
 
+import org.apache.fop.afp.AFPDitheredRectanglePainter;
 import org.apache.fop.afp.AFPPaintingState;
+import org.apache.fop.afp.AFPRectanglePainter;
 import org.apache.fop.afp.AFPResourceLevelDefaults;
 import org.apache.fop.afp.AFPResourceManager;
 import org.apache.fop.afp.AFPUnitConverter;
+import org.apache.fop.afp.AbstractAFPPainter;
 import org.apache.fop.afp.DataStream;
 import org.apache.fop.afp.fonts.AFPFontCollection;
 import org.apache.fop.afp.fonts.AFPPageFonts;
@@ -76,6 +79,9 @@
 
     private int location = LOC_ELSEWHERE;
 
+    /** the shading mode for filled rectangles */
+    private AFPShadingMode shadingMode = AFPShadingMode.COLOR;
+
     /**
      * Default constructor.
      */
@@ -125,6 +131,16 @@
         return this.resourceManager;
     }
 
+    AbstractAFPPainter createRectanglePainter() {
+        if (AFPShadingMode.DITHERED.equals(this.shadingMode)) {
+            return new AFPDitheredRectanglePainter(
+                    getPaintingState(), getDataStream(), getResourceManager());
+        } else {
+            return new AFPRectanglePainter(
+                    getPaintingState(), getDataStream());
+        }
+    }
+
     /** {...@inheritdoc} */
     public void startDocument() throws IFException {
         super.startDocument();
@@ -309,6 +325,11 @@
     }
 
     /** {...@inheritdoc} */
+    public void setShadingMode(AFPShadingMode shadingMode) {
+        this.shadingMode = shadingMode;
+    }
+
+    /** {...@inheritdoc} */
     public void setResolution(int resolution) {
         paintingState.setResolution(resolution);
     }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPPainter.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPPainter.java?rev=769445&r1=769444&r2=769445&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPPainter.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPPainter.java 
Tue Apr 28 16:10:08 2009
@@ -35,8 +35,8 @@
 
 import org.apache.fop.afp.AFPBorderPainter;
 import org.apache.fop.afp.AFPPaintingState;
-import org.apache.fop.afp.AFPRectanglePainter;
 import org.apache.fop.afp.AFPUnitConverter;
+import org.apache.fop.afp.AbstractAFPPainter;
 import org.apache.fop.afp.BorderPaintingInfo;
 import org.apache.fop.afp.DataStream;
 import org.apache.fop.afp.RectanglePaintingInfo;
@@ -79,7 +79,7 @@
     /** the border painter */
     private AFPBorderPainterAdapter borderPainter;
     /** the rectangle painter */
-    private AFPRectanglePainter rectanglePainter;
+    private AbstractAFPPainter rectanglePainter;
 
     /** unit converter */
     private final AFPUnitConverter unitConv;
@@ -94,7 +94,7 @@
         this.state = IFState.create();
         this.borderPainter = new AFPBorderPainterAdapter(
                 new AFPBorderPainter(getPaintingState(), getDataStream()));
-        this.rectanglePainter = new AFPRectanglePainter(getPaintingState(), 
getDataStream());
+        this.rectanglePainter = documentHandler.createRectanglePainter();
         this.unitConv = getPaintingState().getUnitConverter();
     }
 
@@ -222,7 +222,11 @@
             }
             RectanglePaintingInfo rectanglePaintInfo = new 
RectanglePaintingInfo(
                     toPoint(rect.x), toPoint(rect.y), toPoint(rect.width), 
toPoint(rect.height));
-            rectanglePainter.paint(rectanglePaintInfo);
+            try {
+                rectanglePainter.paint(rectanglePaintInfo);
+            } catch (IOException ioe) {
+                throw new IFException("IO error while painting rectangle", 
ioe);
+            }
         }
     }
 

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPRenderer.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPRenderer.java?rev=769445&r1=769444&r2=769445&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPRenderer.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPRenderer.java 
Tue Apr 28 16:10:08 2009
@@ -43,6 +43,7 @@
 
 import org.apache.fop.afp.AFPBorderPainter;
 import org.apache.fop.afp.AFPDataObjectInfo;
+import org.apache.fop.afp.AFPDitheredRectanglePainter;
 import org.apache.fop.afp.AFPEventProducer;
 import org.apache.fop.afp.AFPPaintingState;
 import org.apache.fop.afp.AFPRectanglePainter;
@@ -50,6 +51,7 @@
 import org.apache.fop.afp.AFPResourceManager;
 import org.apache.fop.afp.AFPTextDataInfo;
 import org.apache.fop.afp.AFPUnitConverter;
+import org.apache.fop.afp.AbstractAFPPainter;
 import org.apache.fop.afp.BorderPaintingInfo;
 import org.apache.fop.afp.DataStream;
 import org.apache.fop.afp.RectanglePaintingInfo;
@@ -167,7 +169,10 @@
     /** the image handler registry */
     private final AFPImageHandlerRegistry imageHandlerRegistry;
 
-    private AFPRectanglePainter rectanglePainter;
+    private AbstractAFPPainter rectanglePainter;
+
+    /** the shading mode for filled rectangles */
+    private AFPShadingMode shadingMode = AFPShadingMode.COLOR;
 
     /**
      * Constructor for AFPRenderer.
@@ -201,11 +206,21 @@
 
         this.dataStream = resourceManager.createDataStream(paintingState, 
outputStream);
         this.borderPainter = new AFPBorderPainter(paintingState, dataStream);
-        this.rectanglePainter = new AFPRectanglePainter(paintingState, 
dataStream);
+        this.rectanglePainter = createRectanglePainter();
 
         dataStream.startDocument();
     }
 
+    AbstractAFPPainter createRectanglePainter() {
+        if (AFPShadingMode.DITHERED.equals(this.shadingMode)) {
+            return new AFPDitheredRectanglePainter(
+                    this.paintingState, this.dataStream, this.resourceManager);
+        } else {
+            return new AFPRectanglePainter(
+                    this.paintingState, this.dataStream);
+        }
+    }
+
     /** {...@inheritdoc} */
     public void stopRenderer() throws IOException {
         dataStream.endDocument();
@@ -362,7 +377,12 @@
     /** {...@inheritdoc} */
     public void fillRect(float x, float y, float width, float height) {
         RectanglePaintingInfo rectanglePaintInfo = new 
RectanglePaintingInfo(x, y, width, height);
-        rectanglePainter.paint(rectanglePaintInfo);
+        try {
+            rectanglePainter.paint(rectanglePaintInfo);
+        } catch (IOException ioe) {
+            //TODO not ideal, but the AFPRenderer is legacy
+            throw new RuntimeException("I/O error while painting a filled 
rectangle", ioe);
+        }
     }
 
     /** {...@inheritdoc} */
@@ -728,6 +748,11 @@
     }
 
     /** {...@inheritdoc} */
+    public void setShadingMode(AFPShadingMode shadingMode) {
+        this.shadingMode = shadingMode;
+    }
+
+    /** {...@inheritdoc} */
     public void setResolution(int resolution) {
         paintingState.setResolution(resolution);
     }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java?rev=769445&r1=769444&r2=769445&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
 Tue Apr 28 16:10:08 2009
@@ -299,6 +299,12 @@
         boolean nativeImageSupport = imagesCfg.getAttributeAsBoolean("native", 
false);
         customizable.setNativeImagesSupported(nativeImageSupport);
 
+        // shading (filled rectangles)
+        Configuration shadingCfg = cfg.getChild("shading");
+        AFPShadingMode shadingMode = AFPShadingMode.valueOf(
+                shadingCfg.getValue(AFPShadingMode.COLOR.getName()));
+        customizable.setShadingMode(shadingMode);
+
         // renderer resolution
         Configuration rendererResolutionCfg = 
cfg.getChild("renderer-resolution", false);
         if (rendererResolutionCfg != null) {

Added: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPShadingMode.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPShadingMode.java?rev=769445&view=auto
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPShadingMode.java 
(added)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPShadingMode.java 
Tue Apr 28 16:10:08 2009
@@ -0,0 +1,74 @@
+/*
+ * 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.io.ObjectStreamException;
+import java.io.Serializable;
+
+/** Enumeration class for the AFP shading mode. */
+public final class AFPShadingMode implements Serializable {
+
+    private static final long serialVersionUID = 8579867898716480779L;
+
+    /** the color mode (the default) */
+    public static final AFPShadingMode COLOR = new AFPShadingMode("COLOR");
+    /** the dithered mode */
+    public static final AFPShadingMode DITHERED = new 
AFPShadingMode("DITHERED");
+
+    private String name;
+
+    /**
+     * Constructor to add a new named item.
+     * @param name Name of the item.
+     */
+    private AFPShadingMode(String name) {
+        this.name = name;
+    }
+
+    /** @return the name of the enumeration */
+    public String getName() {
+        return this.name;
+    }
+
+    /**
+     * Returns the enumeration/singleton object based on its name.
+     * @param name the name of the enumeration value
+     * @return the enumeration object
+     */
+    public static AFPShadingMode valueOf(String name) {
+        if (COLOR.getName().equalsIgnoreCase(name)) {
+            return COLOR;
+        } else if (DITHERED.getName().equalsIgnoreCase(name)) {
+            return DITHERED;
+        } else {
+            throw new IllegalArgumentException("Illegal value for enumeration: 
" + name);
+        }
+    }
+
+    private Object readResolve() throws ObjectStreamException {
+        return valueOf(getName());
+    }
+
+    /** {...@inheritdoc} */
+    public String toString() {
+        return getClass().getName() + ":" + name;
+    }
+
+}

Propchange: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPShadingMode.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/afp/AFPShadingMode.java
------------------------------------------------------------------------------
    svn:keywords = Revision Id

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLGenerator.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLGenerator.java?rev=769445&r1=769444&r2=769445&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLGenerator.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pcl/PCLGenerator.java 
Tue Apr 28 16:10:08 2009
@@ -48,6 +48,7 @@
 import org.apache.xmlgraphics.util.UnitConv;
 
 import org.apache.fop.util.bitmap.BitmapImageUtil;
+import org.apache.fop.util.bitmap.DitherUtil;
 import org.apache.fop.util.bitmap.MonochromeBitmapConverter;
 
 /**
@@ -65,11 +66,6 @@
     /** A list of all supported resolutions in PCL (values in dpi) */
     public static final int[] PCL_RESOLUTIONS = new int[] {75, 100, 150, 200, 
300, 600};
 
-    /** Selects a 4x4 Bayer dither matrix (17 grayscales) */
-    public static final int DITHER_MATRIX_4X4 = 4;
-    /** Selects a 8x8 Bayer dither matrix (65 grayscales) */
-    public static final int DITHER_MATRIX_8X8 = 8;
-
     private final DecimalFormatSymbols symbols = new 
DecimalFormatSymbols(Locale.US);
     private final DecimalFormat df2 = new DecimalFormat("0.##", symbols);
     private final DecimalFormat df4 = new DecimalFormat("0.####", symbols);
@@ -390,7 +386,7 @@
             writeCommand("*c" + lineshade + "G");
             writeCommand("*c2P"); //Shaded fill
         } else {
-            defineGrayscalePattern(col, 32, DITHER_MATRIX_4X4);
+            defineGrayscalePattern(col, 32, DitherUtil.DITHER_MATRIX_4X4);
 
             writeCommand("*c" + formatDouble4(w / 100.0) + "h"
                               + formatDouble4(h / 100.0) + "V");
@@ -401,34 +397,6 @@
         setPatternTransparencyMode(true);
     }
 
-    //Bayer dither matrices (4x4 and 8x8 are derived from the 2x2 matrix)
-    private static final int[] BAYER_D2 = new int[] {0, 2, 3, 1};
-    private static final int[] BAYER_D4;
-    private static final int[] BAYER_D8;
-
-    static {
-        BAYER_D4 = deriveBayerMatrix(BAYER_D2);
-        BAYER_D8 = deriveBayerMatrix(BAYER_D4);
-    }
-
-    private static void setValueInMatrix(int[] dn, int half, int part, int 
idx, int value) {
-        int xoff = (part & 1) * half;
-        int yoff = (part & 2) * half * half;
-        int matrixIndex = yoff + ((idx / half) * half * 2) + (idx % half) + 
xoff;
-        dn[matrixIndex] = value;
-    }
-
-    private static int[] deriveBayerMatrix(int[] d) {
-        int[] dn = new int[d.length * 4];
-        int half = (int)Math.sqrt(d.length);
-        for (int part = 0; part < 4; part++) {
-            for (int i = 0, c = d.length; i < c; i++) {
-                setValueInMatrix(dn, half, part, i, d[i] * 4 + BAYER_D2[part]);
-            }
-        }
-        return dn;
-    }
-
     /**
      * Generates a user-defined pattern for a dithering pattern matching the 
grayscale value
      * of the color given.
@@ -453,35 +421,12 @@
 
         byte[] pattern;
         if (ditherMatrixSize == 8) {
-            int gray65 = gray255 * 65 / 255;
-
-            pattern = new byte[BAYER_D8.length / 8];
-
-            for (int i = 0, c = BAYER_D8.length; i < c; i++) {
-                boolean dot = !(BAYER_D8[i] < gray65 - 1);
-                if (dot) {
-                    int byteIdx = i / 8;
-                    pattern[byteIdx] |= 1 << (i % 8);
-                }
-            }
+            pattern = DitherUtil.getBayerDither(DitherUtil.DITHER_MATRIX_8X8, 
gray255, false);
         } else {
-            int gray17 = gray255 * 17 / 255;
-
             //Since a 4x4 pattern did not work, the 4x4 pattern is applied 4 
times to an
             //8x8 pattern. Maybe this could be changed to use an 8x8 bayer 
dither pattern
             //instead of the 4x4 one.
-            pattern = new byte[BAYER_D4.length / 8 * 4];
-
-            for (int i = 0, c = BAYER_D4.length; i < c; i++) {
-                boolean dot = !(BAYER_D4[i] < gray17 - 1);
-                if (dot) {
-                    int byteIdx = i / 4;
-                    pattern[byteIdx] |= 1 << (i % 4);
-                    pattern[byteIdx] |= 1 << ((i % 4) + 4);
-                    pattern[byteIdx + 4] |= 1 << (i % 4);
-                    pattern[byteIdx + 4] |= 1 << ((i % 4) + 4);
-                }
-            }
+            pattern = DitherUtil.getBayerDither(DitherUtil.DITHER_MATRIX_4X4, 
gray255, true);
         }
         data.write(pattern);
         if ((baout.size() % 2) > 0) {
@@ -564,7 +509,7 @@
             if (usePCLShades) {
                 selectCurrentPattern(convertToPCLShade(col), 2);
             } else {
-                defineGrayscalePattern(col, 32, DITHER_MATRIX_4X4);
+                defineGrayscalePattern(col, 32, DitherUtil.DITHER_MATRIX_4X4);
                 selectCurrentPattern(32, 4);
             }
         }

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/util/bitmap/DitherUtil.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/util/bitmap/DitherUtil.java?rev=769445&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/util/bitmap/DitherUtil.java 
(added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/util/bitmap/DitherUtil.java 
Tue Apr 28 16:10:08 2009
@@ -0,0 +1,153 @@
+/*
+ * 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.util.bitmap;
+
+import java.awt.Color;
+
+/**
+ * Utility methods for dithering.
+ */
+public class DitherUtil {
+
+    /** Selects a 2x2 Bayer dither matrix (5 grayscales) */
+    public static final int DITHER_MATRIX_2X2 = 2;
+    /** Selects a 4x4 Bayer dither matrix (17 grayscales) */
+    public static final int DITHER_MATRIX_4X4 = 4;
+    /** Selects a 8x8 Bayer dither matrix (65 grayscales) */
+    public static final int DITHER_MATRIX_8X8 = 8;
+
+    //Bayer dither matrices (4x4 and 8x8 are derived from the 2x2 matrix)
+    private static final int[] BAYER_D2 = new int[] {0, 2, 3, 1};
+    private static final int[] BAYER_D4;
+    private static final int[] BAYER_D8;
+
+    static {
+        BAYER_D4 = deriveBayerMatrix(BAYER_D2);
+        BAYER_D8 = deriveBayerMatrix(BAYER_D4);
+    }
+
+    private static int[] deriveBayerMatrix(int[] d) {
+        int[] dn = new int[d.length * 4];
+        int half = (int)Math.sqrt(d.length);
+        for (int part = 0; part < 4; part++) {
+            for (int i = 0, c = d.length; i < c; i++) {
+                setValueInMatrix(dn, half, part, i, d[i] * 4 + BAYER_D2[part]);
+            }
+        }
+        return dn;
+    }
+
+    private static void setValueInMatrix(int[] dn, int half, int part, int 
idx, int value) {
+        int xoff = (part & 1) * half;
+        int yoff = (part & 2) * half * half;
+        int matrixIndex = yoff + ((idx / half) * half * 2) + (idx % half) + 
xoff;
+        dn[matrixIndex] = value;
+    }
+
+    /**
+     * Returns the Bayer dither base pattern for a particular matrix size.
+     * @param matrix the matrix size ({...@link #DITHER_MATRIX_2X2}, {...@link 
#DITHER_MATRIX_4X4}
+     *                                   or {...@link #DITHER_MATRIX_8X8})
+     * @return the base pattern for the given size
+     */
+    public static int[] getBayerBasePattern(int matrix) {
+        int[] result = new int[matrix * matrix];
+        switch (matrix) {
+        case DITHER_MATRIX_2X2:
+            System.arraycopy(BAYER_D2, 0, result, 0, BAYER_D2.length);
+            break;
+        case DITHER_MATRIX_4X4:
+            System.arraycopy(BAYER_D4, 0, result, 0, BAYER_D4.length);
+            break;
+        case DITHER_MATRIX_8X8:
+            System.arraycopy(BAYER_D8, 0, result, 0, BAYER_D8.length);
+            break;
+        default:
+            throw new IllegalArgumentException("Unsupported dither matrix: " + 
matrix);
+        }
+        return result;
+    }
+
+    /**
+     * Returns a byte array containing the dither pattern for the given 8-bit 
gray value.
+     * @param matrix the matrix size ({...@link #DITHER_MATRIX_2X2}, {...@link 
#DITHER_MATRIX_4X4}
+     *                                   or {...@link #DITHER_MATRIX_8X8})
+     * @param gray255 the gray value (0-255)
+     * @param doubleMatrix true if the 4x4 matrix shall be doubled to a 8x8
+     * @return the dither pattern
+     */
+    public static byte[] getBayerDither(int matrix, int gray255, boolean 
doubleMatrix) {
+        int ditherIndex;
+        byte[] dither;
+        int[] bayer;
+        switch (matrix) {
+        case DITHER_MATRIX_4X4:
+            ditherIndex = gray255 * 17 / 255;
+            bayer = BAYER_D4;
+            break;
+        case DITHER_MATRIX_8X8:
+            ditherIndex = gray255 * 65 / 255;
+            bayer = BAYER_D8;
+            break;
+        default:
+            throw new IllegalArgumentException("Unsupported dither matrix: " + 
matrix);
+        }
+        if (doubleMatrix) {
+            if (doubleMatrix && (matrix != DITHER_MATRIX_4X4)) {
+                throw new IllegalArgumentException("doubleMatrix=true is only 
allowed for 4x4");
+            }
+            dither = new byte[bayer.length / 8 * 4];
+            for (int i = 0, c = bayer.length; i < c; i++) {
+                boolean dot = !(bayer[i] < ditherIndex - 1);
+                if (dot) {
+                    int byteIdx = i / 4;
+                    dither[byteIdx] |= 1 << (i % 4);
+                    dither[byteIdx] |= 1 << ((i % 4) + 4);
+                    dither[byteIdx + 4] |= 1 << (i % 4);
+                    dither[byteIdx + 4] |= 1 << ((i % 4) + 4);
+                }
+            }
+        } else {
+            dither = new byte[bayer.length / 8];
+            for (int i = 0, c = bayer.length; i < c; i++) {
+                boolean dot = !(bayer[i] < ditherIndex - 1);
+                if (dot) {
+                    int byteIdx = i / 8;
+                    dither[byteIdx] |= 1 << (i % 8);
+                }
+            }
+        }
+        return dither;
+    }
+
+    /**
+     * Returns a byte array containing the dither pattern for the given 8-bit 
gray value.
+     * @param matrix the matrix size ({...@link #DITHER_MATRIX_2X2}, {...@link 
#DITHER_MATRIX_4X4}
+     *                                   or {...@link #DITHER_MATRIX_8X8})
+     * @param col the color
+     * @param doubleMatrix true if the 4x4 matrix shall be doubled to a 8x8
+     * @return the dither pattern
+     */
+    public static byte[] getBayerDither(int matrix, Color col, boolean 
doubleMatrix) {
+        float black = BitmapImageUtil.convertToGray(col.getRGB()) / 256f;
+        return getBayerDither(matrix, Math.round(black * 256), doubleMatrix);
+    }
+
+}

Propchange: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/util/bitmap/DitherUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/util/bitmap/DitherUtil.java
------------------------------------------------------------------------------
    svn:keywords = Revision Id

Modified: xmlgraphics/fop/trunk/status.xml
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/status.xml?rev=769445&r1=769444&r2=769445&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/status.xml (original)
+++ xmlgraphics/fop/trunk/status.xml Tue Apr 28 16:10:08 2009
@@ -58,6 +58,9 @@
       documents. Example: the fix of marks layering will be such a case when 
it's done.
     -->
     <release version="FOP Trunk" date="TBD">
+      <action context="Renderers" dev="JM" type="add">
+        Added setting to enable dithered painting of filled rectangles in AFP 
and PCL.
+      </action>
       <action context="Layout" dev="VH" type="fix">
         Bugfix: footnotes occurring within the forced height of a table row 
did not appear on the 
         output



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to