You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by je...@apache.org on 2006/01/24 21:02:40 UTC

svn commit: r372004 - in /xmlgraphics/fop/trunk/src/java/org/apache/fop/render: AbstractRenderer.java ImageAdapter.java Renderer.java ps/PSImageUtils.java ps/PSRenderer.java

Author: jeremias
Date: Tue Jan 24 12:02:30 2006
New Revision: 372004

URL: http://svn.apache.org/viewcvs?rev=372004&view=rev
Log:
Following the model of Graphics2DAdapter, added a new interface ImageAdapter which can optionally be implemented by Renderers to support painting of RenderedImage or BufferedImage instances from inside XMLHandler implementations. First implementation by the PSRenderer. Barcode4J is going to be extended to use this interface so barcode support can easily be added to the AFP Renderer without having a Graphics2D implementation at first.

Added:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ImageAdapter.java
Modified:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractRenderer.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/Renderer.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSImageUtils.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSRenderer.java

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractRenderer.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractRenderer.java?rev=372004&r1=372003&r2=372004&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/AbstractRenderer.java Tue Jan 24 12:02:30 2006
@@ -164,6 +164,11 @@
         return null;
     }
     
+    /** @see org.apache.fop.render.Renderer#getImageAdapter() */
+    public ImageAdapter getImageAdapter() {
+        return null;
+    }
+    
     /** @return the current PageViewport or null, if none is active */
     protected PageViewport getCurrentPageViewport() {
         return this.currentPageViewport;

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ImageAdapter.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ImageAdapter.java?rev=372004&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ImageAdapter.java (added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ImageAdapter.java Tue Jan 24 12:02:30 2006
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed 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;
+
+import java.awt.image.RenderedImage;
+import java.io.IOException;
+
+/**
+ * This interface represents an optional feature that can be provided by
+ * a renderer. It is exposed by calling the getImageAdapter() method
+ * on the renderer. Renderers that support this feature allow painting
+ * of images (RendererImage instances).
+ */
+public interface ImageAdapter {
+
+    /**
+     * Paints an image at the given position.
+     * @param image the image which will be painted
+     * @param context the renderer context for the current renderer
+     * @param x X position of the image
+     * @param y Y position of the image
+     * @param width width of the image
+     * @param height height of the image
+     * @throws IOException In case of an I/O error while writing the output format
+     */
+    void paintImage(RenderedImage image, 
+            RendererContext context,
+            int x, int y, int width, int height) throws IOException;
+    
+}

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/Renderer.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/Renderer.java?rev=372004&r1=372003&r2=372004&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/Renderer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/Renderer.java Tue Jan 24 12:02:30 2006
@@ -122,6 +122,11 @@
     Graphics2DAdapter getGraphics2DAdapter();
     
     /**
+     * @return the adapter for painting RenderedImages (or null if not supported)
+     */
+    ImageAdapter getImageAdapter();
+    
+    /**
      * This is called if the renderer supports out of order rendering. The
      * renderer should prepare the page so that a page further on in the set of
      * pages can be rendered. The body of the page should not be rendered. The

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSImageUtils.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSImageUtils.java?rev=372004&r1=372003&r2=372004&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSImageUtils.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSImageUtils.java Tue Jan 24 12:02:30 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2005 The Apache Software Foundation.
+ * Copyright 2004-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,7 +18,13 @@
  
 package org.apache.fop.render.ps;
 
+import java.awt.Dimension;
 import java.awt.color.ColorSpace;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
 import java.io.IOException;
 import java.io.OutputStream;
 
@@ -64,23 +70,38 @@
                 return;
             }
         }
-        boolean iscolor = img.getColorSpace().getType()
-                          != ColorSpace.CS_GRAY;
         byte[] imgmap;
         if (img.getBitmapsSize() > 0) {
             imgmap = img.getBitmaps();
         } else {
             imgmap = img.getRessourceBytes();
         }
+        
+        String imgName = img.getMimeType() + " " + img.getOriginalURI();
+        Dimension imgDim = new Dimension(img.getWidth(), img.getHeight());
+        Rectangle2D targetRect = new Rectangle2D.Double(x, y, w, h);
+        boolean isJPEG = (img instanceof JpegImage);
+        writeImage(imgmap, imgDim, imgName, targetRect, isJPEG, 
+                img.getColorSpace(), gen);
+    }
+
+    private static void writeImage(byte[] img,
+            Dimension imgDim, String imgName,
+            Rectangle2D targetRect, 
+            boolean isJPEG, ColorSpace colorSpace,
+            PSGenerator gen) throws IOException {
+        boolean iscolor = colorSpace.getType() != ColorSpace.CS_GRAY;
 
         gen.saveGraphicsState();
-        gen.writeln(x + " " + y + " translate");
-        gen.writeln(w + " " + h + " scale");
+        gen.writeln(gen.formatDouble(targetRect.getX()) + " " 
+                + gen.formatDouble(targetRect.getY()) + " translate");
+        gen.writeln(gen.formatDouble(targetRect.getWidth()) + " " 
+                + gen.formatDouble(targetRect.getHeight()) + " scale");
 
-        gen.commentln("%FOPBeginBitmap: " + img.getMimeType() + " " + img.getOriginalURI());
-        if (img.getColorSpace().getType() == ColorSpace.TYPE_CMYK) {
+        gen.commentln("%FOPBeginBitmap: " + imgName);
+        if (colorSpace.getType() == ColorSpace.TYPE_CMYK) {
             gen.writeln("/DeviceCMYK setcolorspace");
-        } else if (img.getColorSpace().getType() == ColorSpace.CS_GRAY) {
+        } else if (colorSpace.getType() == ColorSpace.CS_GRAY) {
             gen.writeln("/DeviceGray setcolorspace");
         } else {
             gen.writeln("/DeviceRGB setcolorspace");
@@ -90,7 +111,7 @@
         // Template: (RawData is used for the EOF signal only)
         // gen.write("/RawData currentfile <first filter> filter def");
         // gen.write("/Data RawData <second filter> <third filter> [...] def");
-        if (img instanceof JpegImage) {
+        if (isJPEG) {
             gen.writeln("/RawData currentfile /ASCII85Decode filter def");
             gen.writeln("/Data RawData << >> /DCTDecode filter def");
         } else {
@@ -104,10 +125,10 @@
         }
         gen.writeln("<<");
         gen.writeln("  /ImageType 1");
-        gen.writeln("  /Width " + img.getWidth());
-        gen.writeln("  /Height " + img.getHeight());
+        gen.writeln("  /Width " + imgDim.width);
+        gen.writeln("  /Height " + imgDim.height);
         gen.writeln("  /BitsPerComponent 8");
-        if (img.getColorSpace().getType() == ColorSpace.TYPE_CMYK) {
+        if (colorSpace.getType() == ColorSpace.TYPE_CMYK) {
             if (false /*TODO img.invertImage()*/) {
                 gen.writeln("  /Decode [1 0 1 0 1 0 1 0]");
             } else {
@@ -119,8 +140,8 @@
             gen.writeln("  /Decode [0 1]");
         }
         // Setup scanning for left-to-right and top-to-bottom
-        gen.writeln("  /ImageMatrix [" + img.getWidth() + " 0 0 "
-              + img.getHeight() + " 0 0]");
+        gen.writeln("  /ImageMatrix [" + imgDim.width + " 0 0 "
+              + imgDim.height + " 0 0]");
 
         gen.writeln("  /DataSource Data");
         gen.writeln(">>");
@@ -135,7 +156,7 @@
 
         OutputStream out = gen.getOutputStream();
         out = new ASCII85OutputStream(out);
-        if (img instanceof JpegImage) {
+        if (isJPEG) {
             //nop
         } else {
             if (gen.getPSLevel() >= 3) {
@@ -144,7 +165,7 @@
                 out = new RunLengthEncodeOutputStream(out);
             }
         }
-        out.write(imgmap);
+        out.write(img);
         if (out instanceof Finalizable) {
             ((Finalizable)out).finalizeStream();
         } else {
@@ -156,6 +177,95 @@
         gen.restoreGraphicsState();
     }
 
+    /**
+     * Renders a bitmap image to PostScript.
+     * @param img image to render
+     * @param x x position
+     * @param y y position
+     * @param w width
+     * @param h height
+     * @param gen PS generator
+     * @throws IOException In case of an I/O problem while rendering the image
+     */
+    public static void renderBitmapImage(RenderedImage img, 
+                float x, float y, float w, float h, PSGenerator gen)
+                    throws IOException {
+        byte[] imgmap = getBitmapBytes(img);
+
+        String imgName = img.getClass().getName();
+        Dimension imgDim = new Dimension(img.getWidth(), img.getHeight());
+        Rectangle2D targetRect = new Rectangle2D.Double(x, y, w, h);
+        boolean isJPEG = false;
+        writeImage(imgmap, imgDim, imgName, targetRect, isJPEG, 
+                img.getColorModel().getColorSpace(), gen);
+    }
+
+    private static byte[] getBitmapBytes(RenderedImage img) {
+        int[] tmpMap = getRGB(img, 0, 0, img.getWidth(), img.getHeight(), null, 0, img.getWidth());
+        // Should take care of the ColorSpace and bitsPerPixel
+        byte[] bitmaps = new byte[img.getWidth() * img.getHeight() * 3];
+        for (int y = 0, my = img.getHeight(); y < my; y++) {
+            for (int x = 0, mx = img.getWidth(); x < mx; x++) {
+                int p = tmpMap[y * mx + x];
+                int r = (p >> 16) & 0xFF;
+                int g = (p >> 8) & 0xFF;
+                int b = (p) & 0xFF;
+                bitmaps[3 * (y * mx + x)] = (byte)(r & 0xFF);
+                bitmaps[3 * (y * mx + x) + 1] = (byte)(g & 0xFF);
+                bitmaps[3 * (y * mx + x) + 2] = (byte)(b & 0xFF);
+            }
+        }
+        return bitmaps;
+    }
+    
+    public static int[] getRGB(RenderedImage img,
+                int startX, int startY, int w, int h,
+                int[] rgbArray, int offset, int scansize) {
+        Raster raster = img.getData();
+        int yoff  = offset;
+        int off;
+        Object data;
+        int nbands = raster.getNumBands();
+        int dataType = raster.getDataBuffer().getDataType();
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new byte[nbands];
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new short[nbands];
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new int[nbands];
+            break;
+        case DataBuffer.TYPE_FLOAT:
+            data = new float[nbands];
+            break;
+        case DataBuffer.TYPE_DOUBLE:
+            data = new double[nbands];
+            break;
+        default:
+            throw new IllegalArgumentException("Unknown data buffer type: "+
+                                               dataType);
+        }
+        
+        if (rgbArray == null) {
+            rgbArray = new int[offset+h*scansize];
+        }
+        
+        ColorModel colorModel = img.getColorModel();
+        for (int y = startY; y < startY+h; y++, yoff+=scansize) {
+            off = yoff;
+            for (int x = startX; x < startX+w; x++) {
+                rgbArray[off++] = colorModel.getRGB(raster.getDataElements(x,
+                                    y,
+                                    data));
+            }
+        }
+        
+        return rgbArray;
+
+    }
+    
     public static void renderEPS(EPSImage img, 
             float x, float y, float w, float h,
             PSGenerator gen) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSRenderer.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSRenderer.java?rev=372004&r1=372003&r2=372004&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/ps/PSRenderer.java Tue Jan 24 12:02:30 2006
@@ -21,6 +21,7 @@
 // Java
 import java.awt.Color;
 import java.awt.geom.Rectangle2D;
+import java.awt.image.RenderedImage;
 import java.io.IOException;
 import java.io.LineNumberReader;
 import java.io.OutputStream;
@@ -63,6 +64,7 @@
 import org.apache.fop.image.XMLImage;
 import org.apache.fop.render.Graphics2DAdapter;
 import org.apache.fop.render.AbstractPathOrientedRenderer;
+import org.apache.fop.render.ImageAdapter;
 import org.apache.fop.render.RendererContext;
 import org.apache.fop.render.ps.extensions.PSSetupCode;
 import org.apache.fop.util.CharUtilities;
@@ -88,7 +90,7 @@
  * @author <a href="mailto:fop-dev@xmlgraphics.apache.org">Apache FOP Development Team</a>
  * @version $Id$
  */
-public class PSRenderer extends AbstractPathOrientedRenderer {
+public class PSRenderer extends AbstractPathOrientedRenderer implements ImageAdapter {
 
     /** The MIME type for PostScript */
     public static final String MIME_TYPE = "application/postscript";
@@ -154,6 +156,11 @@
         return new PSGraphics2DAdapter(this);
     }
 
+    /** @see org.apache.fop.render.Renderer#getImageAdapter() */
+    public ImageAdapter getImageAdapter() {
+        return this;
+    }
+
     /**
      * Write out a command
      * @param cmd PostScript command
@@ -303,6 +310,16 @@
         }
     }
 
+    public void paintImage(RenderedImage image, RendererContext context, int x, int y, int width, int height) throws IOException {
+        float fx = (float)x / 1000f;
+        x += currentIPPosition / 1000f;
+        float fy = (float)y / 1000f;
+        y += currentBPPosition / 1000f;
+        float fw = (float)width / 1000f;
+        float fh = (float)height / 1000f;
+        PSImageUtils.renderBitmapImage(image, fx, fy, fw, fh, gen);
+    }
+
     /**
      * Draw a line.
      *
@@ -740,7 +757,8 @@
         gen.writeDSCComment(DSCConstants.BEGIN_PAGE_SETUP);
         
         //Handle PSSetupCode instances on simple-page-master
-        if (page.getExtensionAttachments().size() > 0) {
+        if (page.getExtensionAttachments() != null 
+                && page.getExtensionAttachments().size() > 0) {
             List list = new java.util.ArrayList();
             //Extract all PSSetupCode instances from the attachment list on the s-p-m
             Iterator i = page.getExtensionAttachments().iterator();
@@ -1103,5 +1121,6 @@
     public String getMimeType() {
         return MIME_TYPE;
     }
+
 
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org