Author: jeremias
Date: Thu Oct 30 01:49:44 2008
New Revision: 709119

URL: http://svn.apache.org/viewvc?rev=709119&view=rev
Log:
Re-Implemented "quality" rendering mode (painting borders and rules using 
bitmaps).
Added a new rendering mode "bitmap" (in addition to "speed" and "bitmap") that 
uses Java2DPainter for the whole page and paints a single bitmap (much like 
most PCL drivers operate). Quality: "speed" < "quality" < "bitmap", 
Performance: "speed" > "quality" > "bitmap" (at high page complexity "bitmap" 
might actually be better), File Size: "speed" < "quality" < "bitmap"
Increased bitmap encoding performance by up to 100% (by optimizing the Java 
code and by supporting the "zeroed row" PCL command)

Added:
    
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java
   (with props)
Modified:
    
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
    
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/DefaultMonochromeBitmapConverter.java
    
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java
    
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLGenerator.java
    
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPageDefinition.java
    
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPainter.java
    
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderer.java
    
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
    
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java

Modified: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java?rev=709119&r1=709118&r2=709119&view=diff
==============================================================================
--- 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
 (original)
+++ 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
 Thu Oct 30 01:49:44 2008
@@ -21,6 +21,7 @@
 
 import java.awt.Color;
 import java.awt.Dimension;
+import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.geom.AffineTransform;
 import java.io.FileNotFoundException;
@@ -47,6 +48,8 @@
 import org.apache.fop.render.ImageHandler;
 import org.apache.fop.render.ImageHandlerRegistry;
 import org.apache.fop.render.RenderingContext;
+import org.apache.fop.traits.BorderProps;
+import org.apache.fop.traits.RuleStyle;
 
 /**
  * Abstract base class for IFPainter implementations.
@@ -195,8 +198,8 @@
                         + effImage.getInfo() + " (" + 
effImage.getClass().getName() + ")");
         }
 
-        if (log.isDebugEnabled()) {
-            log.debug("Using ImageHandler: " + handler.getClass().getName());
+        if (log.isTraceEnabled()) {
+            log.trace("Using ImageHandler: " + handler.getClass().getName());
         }
 
         //TODO foreign attributes
@@ -262,6 +265,67 @@
     }
 
     /** [EMAIL PROTECTED] */
+    public void drawBorderRect(Rectangle rect, BorderProps before, BorderProps 
after,
+            BorderProps start, BorderProps end) throws IFException {
+        if (before != null) {
+            Rectangle b = new Rectangle(
+                    rect.x, rect.y,
+                    rect.width, before.width);
+            fillRect(b, before.color);
+        }
+        if (end != null) {
+            Rectangle b = new Rectangle(
+                    rect.x + rect.width - end.width, rect.y,
+                    end.width, rect.height);
+            fillRect(b, end.color);
+        }
+        if (after != null) {
+            Rectangle b = new Rectangle(
+                    rect.x, rect.y + rect.height - after.width,
+                    rect.width, after.width);
+            fillRect(b, after.color);
+        }
+        if (start != null) {
+            Rectangle b = new Rectangle(
+                    rect.x, rect.y,
+                    start.width, rect.height);
+            fillRect(b, start.color);
+        }
+    }
+
+    /** [EMAIL PROTECTED] */
+    public void drawLine(Point start, Point end, int width, Color color, 
RuleStyle style)
+            throws IFException {
+        Rectangle rect = getLineBoundingBox(start, end, width);
+        fillRect(rect, color);
+    }
+
+    /**
+     * Calculates the bounding box for a line. Currently, only horizontal and 
vertical lines
+     * are needed and supported.
+     * @param start the starting point of the line (coordinates in mpt)
+     * @param end the ending point of the line (coordinates in mpt)
+     * @param width the line width (in mpt)
+     * @return the bounding box (coordinates in mpt)
+     */
+    protected Rectangle getLineBoundingBox(Point start, Point end, int width) {
+        if (start.y == end.y) {
+            int topy = start.y - width / 2;
+            return new Rectangle(
+                    start.x, topy,
+                    end.x - start.x, width);
+        } else if (start.x == end.y) {
+            int leftx = start.x - width / 2;
+            return new Rectangle(
+                    leftx, start.x,
+                    width, end.y - start.y);
+        } else {
+            throw new IllegalArgumentException(
+                    "Only horizontal or vertical lines are supported at the 
moment.");
+        }
+    }
+
+    /** [EMAIL PROTECTED] */
     public void setFont(String family, String style, Integer weight, String 
variant, Integer size,
             Color color) throws IFException {
         if (family != null) {

Modified: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/DefaultMonochromeBitmapConverter.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/DefaultMonochromeBitmapConverter.java?rev=709119&r1=709118&r2=709119&view=diff
==============================================================================
--- 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/DefaultMonochromeBitmapConverter.java
 (original)
+++ 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/DefaultMonochromeBitmapConverter.java
 Thu Oct 30 01:49:44 2008
@@ -32,9 +32,13 @@
 public class DefaultMonochromeBitmapConverter implements
         MonochromeBitmapConverter {
 
+    private boolean quality = false;
+
     /** [EMAIL PROTECTED] */
     public void setHint(String name, String value) {
-        //ignore, not supported
+        if ("quality".equalsIgnoreCase(name)) {
+            quality = "true".equalsIgnoreCase(value);
+        }
     }
 
     /** [EMAIL PROTECTED] */
@@ -42,8 +46,16 @@
         BufferedImage buf = new BufferedImage(img.getWidth(), img.getHeight(),
                 BufferedImage.TYPE_BYTE_BINARY);
         RenderingHints hints = new RenderingHints(null);
-        //This hint doesn't seem to make a difference :-(
-        hints.put(RenderingHints.KEY_DITHERING, 
RenderingHints.VALUE_DITHER_ENABLE);
+        //These hints don't seem to make a difference :-( Not seeing any 
dithering on Sun Java.
+        hints.put(RenderingHints.KEY_DITHERING,
+                RenderingHints.VALUE_DITHER_ENABLE);
+        if (quality) {
+            hints.put(RenderingHints.KEY_RENDERING,
+                    RenderingHints.VALUE_RENDER_QUALITY);
+            hints.put(RenderingHints.KEY_COLOR_RENDERING,
+                    RenderingHints.VALUE_COLOR_RENDER_QUALITY);
+        }
+
         ColorConvertOp op = new ColorConvertOp(
                 ColorSpace.getInstance(ColorSpace.CS_GRAY), hints);
         op.filter(img, buf);

Modified: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java?rev=709119&r1=709118&r2=709119&view=diff
==============================================================================
--- 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java
 (original)
+++ 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java
 Thu Oct 30 01:49:44 2008
@@ -19,18 +19,27 @@
 
 package org.apache.fop.render.pcl;
 
+import java.awt.Color;
 import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
 import java.io.IOException;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import org.apache.xmlgraphics.util.UnitConv;
+
 import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.FopFactoryConfigurator;
 import org.apache.fop.apps.MimeConstants;
 import 
org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler;
 import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
 import org.apache.fop.render.intermediate.IFException;
 import org.apache.fop.render.intermediate.IFPainter;
+import org.apache.fop.render.java2d.Java2DPainter;
 
 /**
  * [EMAIL PROTECTED] IFDocumentHandler} implementation that produces PCL 5.
@@ -54,6 +63,10 @@
     /** contains the pageHeight of the last printed page */
     private long pageHeight = 0;
 
+    /** the current page image (only set when all-bitmap painting is 
activated) */
+    private BufferedImage currentImage;
+
+
     /**
      * Default constructor.
      */
@@ -190,12 +203,74 @@
 
     /** [EMAIL PROTECTED] */
     public IFPainter startPageContent() throws IFException {
-        return new PCLPainter(this, this.currentPageDefinition);
+        if (pclUtil.getRenderingMode() == PCLRenderingMode.BITMAP) {
+            return createAllBitmapPainter();
+        } else {
+            return new PCLPainter(this, this.currentPageDefinition);
+        }
+    }
+
+    private IFPainter createAllBitmapPainter() {
+        double scale = gen.getMaximumBitmapResolution()
+                / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION;
+        Rectangle printArea = this.currentPageDefinition.getLogicalPageRect();
+        int bitmapWidth = (int)Math.ceil(
+                UnitConv.mpt2px(printArea.width, 
gen.getMaximumBitmapResolution()));
+        int bitmapHeight = (int)Math.ceil(
+                UnitConv.mpt2px(printArea.height, 
gen.getMaximumBitmapResolution()));
+        this.currentImage = createBufferedImage(bitmapWidth, bitmapHeight);
+        Graphics2D graphics2D = this.currentImage.createGraphics();
+
+        if (!PCLGenerator.isJAIAvailable()) {
+            RenderingHints hints = new RenderingHints(null);
+            //These hints don't seem to make a difference :-( Not seeing any 
dithering on Sun Java.
+            hints.put(RenderingHints.KEY_DITHERING,
+                    RenderingHints.VALUE_DITHER_ENABLE);
+            graphics2D.addRenderingHints(hints);
+        }
+
+        //Ensure white page background
+        graphics2D.setBackground(Color.WHITE);
+        graphics2D.clearRect(0, 0, bitmapWidth, bitmapHeight);
+
+        graphics2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
+                RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+        graphics2D.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
+                RenderingHints.VALUE_STROKE_PURE);
+        graphics2D.scale(scale / 1000f, scale / 1000f);
+        graphics2D.translate(-printArea.x, -printArea.y);
+
+        return new Java2DPainter(graphics2D, getUserAgent(), getFontInfo());
+    }
+
+    private BufferedImage createBufferedImage(int bitmapWidth, int 
bitmapHeight) {
+        int bitmapType;
+        if (PCLGenerator.isJAIAvailable()) {
+            //TYPE_BYTE_GRAY was used to work around the lack of dithering 
when using
+            //TYPE_BYTE_BINARY. Adding RenderingHints didn't help.
+            bitmapType = BufferedImage.TYPE_BYTE_GRAY;
+            //bitmapType = BufferedImage.TYPE_INT_RGB; //Use to enable Batik 
gradients
+        } else {
+            bitmapType = BufferedImage.TYPE_BYTE_BINARY;
+        }
+        return new BufferedImage(
+                bitmapWidth, bitmapHeight, bitmapType);
     }
 
     /** [EMAIL PROTECTED] */
     public void endPageContent() throws IFException {
-        //nop
+        if (this.currentImage != null) {
+            try {
+                //ImageWriterUtil.saveAsPNG(this.currentImage, new 
java.io.File("D:/page.png"));
+                Rectangle printArea = 
this.currentPageDefinition.getLogicalPageRect();
+                gen.setCursorPos(0, 0);
+                gen.paintBitmap(this.currentImage, printArea.getSize(), true);
+            } catch (IOException ioe) {
+                throw new IFException("I/O error while encoding page image", 
ioe);
+            } finally {
+                this.currentImage = null;
+            }
+        }
     }
 
     /** [EMAIL PROTECTED] */

Modified: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLGenerator.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLGenerator.java?rev=709119&r1=709118&r2=709119&view=diff
==============================================================================
--- 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLGenerator.java
 (original)
+++ 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLGenerator.java
 Thu Oct 30 01:49:44 2008
@@ -30,8 +30,10 @@
 import java.awt.image.ColorConvertOp;
 import java.awt.image.ColorModel;
 import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
 import java.awt.image.IndexColorModel;
 import java.awt.image.LookupOp;
+import java.awt.image.MultiPixelPackedSampleModel;
 import java.awt.image.Raster;
 import java.awt.image.RenderedImage;
 import java.awt.image.WritableRaster;
@@ -604,6 +606,26 @@
         return (img.getColorModel().getNumColorComponents() == 1);
     }
 
+    private static int jaiAvailable = -1; //no synchronization necessary, not 
critical
+
+    /**
+     * Indicates whether JAI is available. JAI has shown to be reliable when 
dithering a
+     * grayscale or color image to monochrome bitmaps (1-bit).
+     * @return true if JAI is available
+     */
+    public static boolean isJAIAvailable() {
+        if (jaiAvailable < 0) {
+            try {
+                String clName = 
"org.apache.fop.render.pcl.JAIMonochromeBitmapConverter";
+                Class.forName(clName);
+                jaiAvailable = 1;
+            } catch (ClassNotFoundException cnfe) {
+                jaiAvailable = 0;
+            }
+        }
+        return (jaiAvailable > 0);
+    }
+
     private MonochromeBitmapConverter createMonochromeBitmapConverter() {
         MonochromeBitmapConverter converter = null;
         try {
@@ -839,6 +861,16 @@
         g2d.clearRect(0, 0, effDim.width, effDim.height);
     }
 
+    private int toGray(int rgb) {
+        // see http://www.jguru.com/faq/view.jsp?EID=221919
+        double greyVal = 0.072169d * (rgb & 0xff);
+        rgb >>= 8;
+        greyVal += 0.715160d * (rgb & 0xff);
+        rgb >>= 8;
+        greyVal += 0.212671d * (rgb & 0xff);
+        return (int)greyVal;
+    }
+
     /**
      * Paint a bitmap at the current cursor position. The bitmap must be a 
monochrome
      * (1-bit) bitmap image.
@@ -850,79 +882,159 @@
         if (!isValidPCLResolution(resolution)) {
             throw new IllegalArgumentException("Invalid PCL resolution: " + 
resolution);
         }
-        setRasterGraphicsResolution(resolution);
-        writeCommand("*r0f" + img.getHeight() + "t" + img.getWidth() + "s1A");
-        Raster raster = img.getData();
         boolean monochrome = isMonochromeImage(img);
         if (!monochrome) {
             throw new IllegalArgumentException("img must be a monochrome 
image");
         }
 
-        int x = 0;
-        int y = 0;
-        int imgw = img.getWidth();
-        int imgh = img.getHeight();
-        int bytewidth = (imgw / 8);
-        if ((imgw % 8) != 0) {
-            bytewidth++;
-        }
-        byte ib;
-        byte[] rle = new byte[bytewidth * 2]; //compressed (RLE)
-        byte[] uncompressed = new byte[bytewidth]; //uncompressed
-        int lastcount = -1;
-        byte lastbyte = 0;
-        int rlewidth = 0;
+        setRasterGraphicsResolution(resolution);
+        writeCommand("*r0f" + img.getHeight() + "t" + img.getWidth() + "s1A");
+        Raster raster = img.getData();
 
+        Encoder encoder = new Encoder(img);
         // Transfer graphics data
-        for (y = 0; y < imgh; y++) {
-            ib = 0;
-            for (x = 0; x < imgw; x++) {
-                int sample = raster.getSample(x, y, 0);
-                //Set image bit for black
-                if ((sample == 0)) {
-                    ib |= (1 << (7 - (x % 8)));
-                }
-
-                //RLE encoding
-                if ((x % 8) == 7 || ((x + 1) == imgw)) {
-                    if (rlewidth < bytewidth) {
-                        if (lastcount >= 0) {
-                            if (ib == lastbyte) {
-                                lastcount++;
-                            } else {
-                                rle[rlewidth++] = (byte)(lastcount & 0xFF);
-                                rle[rlewidth++] = lastbyte;
-                                lastbyte = ib;
-                                lastcount = 0;
-                            }
+        int imgw = img.getWidth();
+        IndexColorModel cm = (IndexColorModel)img.getColorModel();
+        if (cm.getTransferType() == DataBuffer.TYPE_BYTE) {
+            DataBufferByte dataBuffer = (DataBufferByte)raster.getDataBuffer();
+            MultiPixelPackedSampleModel packedSampleModel = new 
MultiPixelPackedSampleModel(
+                    DataBuffer.TYPE_BYTE, img.getWidth(), img.getHeight(), 1);
+            if (img.getSampleModel().equals(packedSampleModel)
+                    && dataBuffer.getNumBanks() == 1) {
+                //Optimized packed encoding
+                byte[] buf = dataBuffer.getData();
+                int scanlineStride = packedSampleModel.getScanlineStride();
+                int idx = 0;
+                int c0 = toGray(cm.getRGB(0));
+                int c1 = toGray(cm.getRGB(1));
+                boolean zeroIsWhite = c0 > c1;
+                for (int y = 0, maxy = img.getHeight(); y < maxy; y++) {
+                    for (int x = 0, maxx = scanlineStride; x < maxx; x++) {
+                        if (zeroIsWhite) {
+                            encoder.add8Bits(buf[idx]);
                         } else {
-                            lastbyte = ib;
-                            lastcount = 0;
-                        }
-                        if (lastcount == 255 || ((x + 1) == imgw)) {
-                            rle[rlewidth++] = (byte)(lastcount & 0xFF);
-                            rle[rlewidth++] = lastbyte;
-                            lastbyte = 0;
-                            lastcount = -1;
+                            encoder.add8Bits((byte)~buf[idx]);
                         }
+                        idx++;
                     }
-                    uncompressed[x / 8] = ib;
-                    ib = 0;
+                    encoder.endLine();
+                }
+            } else {
+                //Optimized non-packed encoding
+                for (int y = 0, maxy = img.getHeight(); y < maxy; y++) {
+                    byte[] line = (byte[])raster.getDataElements(0, y, imgw, 
1, null);
+                    for (int x = 0, maxx = imgw; x < maxx; x++) {
+                        encoder.addBit(line[x] == 0);
+                    }
+                    encoder.endLine();
+                }
+            }
+        } else {
+            //Safe but slow fallback
+            for (int y = 0, maxy = img.getHeight(); y < maxy; y++) {
+                for (int x = 0, maxx = imgw; x < maxx; x++) {
+                    int sample = raster.getSample(x, y, 0);
+                    encoder.addBit(sample == 0);
                 }
+                encoder.endLine();
             }
+        }
+
+        // End raster graphics
+        writeCommand("*rB");
+    }
+
+    private class Encoder {
+
+        private int imgw;
+        private int bytewidth;
+        private byte[] rle; //compressed (RLE)
+        private byte[] uncompressed; //uncompressed
+        private int lastcount = -1;
+        private byte lastbyte = 0;
+        private int rlewidth = 0;
+        private byte ib = 0; //current image bits
+        private int x = 0;
+        private boolean zeroRow = true;
+
+        public Encoder(RenderedImage img) {
+            imgw = img.getWidth();
+            bytewidth = (imgw / 8);
+            if ((imgw % 8) != 0) {
+                bytewidth++;
+            }
+            rle = new byte[bytewidth * 2];
+            uncompressed = new byte[bytewidth];
+        }
+
+        public void addBit(boolean bit) {
+            //Set image bit for black
+            if (bit) {
+                ib |= 1;
+            }
+
+            //RLE encoding
+            if ((x % 8) == 7 || ((x + 1) == imgw)) {
+                finishedByte();
+            } else {
+                ib <<= 1;
+            }
+            x++;
+        }
+
+        public void add8Bits(byte b) {
+            ib = b;
+            finishedByte();
+            x += 8;
+        }
+
+        private void finishedByte() {
             if (rlewidth < bytewidth) {
+                if (lastcount >= 0) {
+                    if (ib == lastbyte) {
+                        lastcount++;
+                    } else {
+                        rle[rlewidth++] = (byte)(lastcount & 0xFF);
+                        rle[rlewidth++] = lastbyte;
+                        lastbyte = ib;
+                        lastcount = 0;
+                    }
+                } else {
+                    lastbyte = ib;
+                    lastcount = 0;
+                }
+                if (lastcount == 255 || ((x + 1) == imgw)) {
+                    rle[rlewidth++] = (byte)(lastcount & 0xFF);
+                    rle[rlewidth++] = lastbyte;
+                    lastbyte = 0;
+                    lastcount = -1;
+                }
+            }
+            uncompressed[x / 8] = ib;
+            if (ib != 0) {
+                zeroRow = false;
+            }
+            ib = 0;
+        }
+
+        public void endLine() throws IOException {
+            if (zeroRow) {
+                writeCommand("*b1Y");
+            } else if (rlewidth < bytewidth) {
                 writeCommand("*b1m" + rlewidth + "W");
-                this.out.write(rle, 0, rlewidth);
+                out.write(rle, 0, rlewidth);
             } else {
                 writeCommand("*b0m" + bytewidth + "W");
-                this.out.write(uncompressed);
+                out.write(uncompressed);
             }
             lastcount = -1;
             rlewidth = 0;
+            ib = 0;
+            x = 0;
+            zeroRow = true;
         }
 
-        // End raster graphics
-        writeCommand("*rB");
+
     }
 
 }

Modified: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPageDefinition.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPageDefinition.java?rev=709119&r1=709118&r2=709119&view=diff
==============================================================================
--- 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPageDefinition.java
 (original)
+++ 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPageDefinition.java
 Thu Oct 30 01:49:44 2008
@@ -114,6 +114,22 @@
         return null;
     }
 
+    /**
+     * Returns a page definition based on a page format.
+     * @param name the name of the page format (ex. "A4" or "Letter")
+     * @return the page definition or null if no match was found
+     */
+    public static PCLPageDefinition getPageDefinition(String name) {
+        Iterator iter = pageDefinitions.iterator();
+        while (iter.hasNext()) {
+            PCLPageDefinition def = (PCLPageDefinition)iter.next();
+            if (def.getName().equalsIgnoreCase(name)) {
+                return def;
+            }
+        }
+        return null;
+    }
+
     /** @return the default page definition (letter) */
     public static PCLPageDefinition getDefaultPageDefinition() {
         return defaultPageDefinition;

Modified: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPainter.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPainter.java?rev=709119&r1=709118&r2=709119&view=diff
==============================================================================
--- 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPainter.java
 (original)
+++ 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLPainter.java
 Thu Oct 30 01:49:44 2008
@@ -66,7 +66,7 @@
     /** logging instance */
     private static Log log = LogFactory.getLog(PCLPainter.class);
 
-    private final boolean DEBUG = false;
+    private static final boolean DEBUG = false;
 
     private PCLDocumentHandler parent;
 
@@ -173,10 +173,7 @@
     /** [EMAIL PROTECTED] */
     public void clipRect(Rectangle rect) throws IFException {
         //PCL cannot clip (only HP GL/2 can)
-        /*
-        generator.endTextObject();
-        generator.clipRect(rect);
-        */
+        //If you need clipping support, switch to RenderingMode.BITMAP.
     }
 
     /** [EMAIL PROTECTED] */
@@ -203,23 +200,97 @@
     }
 
     /** [EMAIL PROTECTED] */
-    public void drawBorderRect(Rectangle rect, BorderProps before, BorderProps 
after,
-            BorderProps start, BorderProps end) throws IFException {
+    public void drawBorderRect(final Rectangle rect,
+            final BorderProps before, final BorderProps after,
+            final BorderProps start, final BorderProps end) throws IFException 
{
+        if (getPCLUtil().getRenderingMode() == PCLRenderingMode.SPEED) {
+            super.drawBorderRect(rect, before, after, start, end);
+            return;
+        }
         if (before != null || after != null || start != null || end != null) {
-            /*
-            generator.endTextObject();
-            this.borderPainter.drawBorders(rect, before, after, start, end);
-            */
+            final Rectangle boundingBox = rect;
+            final Dimension dim = boundingBox.getSize();
+
+            Graphics2DImagePainter painter = new Graphics2DImagePainter() {
+
+                public void paint(Graphics2D g2d, Rectangle2D area) {
+                    g2d.translate(-rect.x, -rect.y);
+
+                    Java2DPainter painter = new Java2DPainter(g2d,
+                            getUserAgent(), parent.getFontInfo(), state);
+                    try {
+                        painter.drawBorderRect(rect, before, after, start, 
end);
+                    } catch (IFException e) {
+                        //This should never happen with the Java2DPainter
+                        throw new RuntimeException("Unexpected error while 
painting borders", e);
+                    }
+                }
+
+                public Dimension getImageSize() {
+                    return dim.getSize();
+                }
+
+            };
+            paintMarksAsBitmap(painter, boundingBox);
         }
     }
 
     /** [EMAIL PROTECTED] */
-    public void drawLine(Point start, Point end, int width, Color color, 
RuleStyle style)
+    public void drawLine(final Point start, final Point end,
+                final int width, final Color color, final RuleStyle style)
+            throws IFException {
+        if (getPCLUtil().getRenderingMode() == PCLRenderingMode.SPEED) {
+            super.drawLine(start, end, width, color, style);
+            return;
+        }
+        final Rectangle boundingBox = getLineBoundingBox(start, end, width);
+        final Dimension dim = boundingBox.getSize();
+
+        Graphics2DImagePainter painter = new Graphics2DImagePainter() {
+
+            public void paint(Graphics2D g2d, Rectangle2D area) {
+                g2d.translate(-boundingBox.x, -boundingBox.y);
+
+                Java2DPainter painter = new Java2DPainter(g2d,
+                        getUserAgent(), parent.getFontInfo(), state);
+                try {
+                    painter.drawLine(start, end, width, color, style);
+                } catch (IFException e) {
+                    //This should never happen with the Java2DPainter
+                    throw new RuntimeException("Unexpected error while 
painting a line", e);
+                }
+            }
+
+            public Dimension getImageSize() {
+                return dim.getSize();
+            }
+
+        };
+        paintMarksAsBitmap(painter, boundingBox);
+    }
+
+    private void paintMarksAsBitmap(Graphics2DImagePainter painter, Rectangle 
boundingBox)
             throws IFException {
-        /*
-        generator.endTextObject();
-        this.borderPainter.drawLine(start, end, width, color, style);
-        */
+        ImageInfo info = new ImageInfo(null, null);
+        ImageSize size = new ImageSize();
+        size.setSizeInMillipoints(boundingBox.width, boundingBox.height);
+        info.setSize(size);
+        ImageGraphics2D img = new ImageGraphics2D(info, painter);
+
+        Map hints = new java.util.HashMap();
+        hints.put(ImageProcessingHints.BITMAP_TYPE_INTENT,
+                ImageProcessingHints.BITMAP_TYPE_INTENT_GRAY);
+        PCLRenderingContext context = 
(PCLRenderingContext)createRenderingContext();
+        context.setSourceTransparencyEnabled(true);
+        try {
+            drawImage(img, boundingBox, context, true, hints);
+        } catch (IOException ioe) {
+            throw new IFException(
+                    "I/O error while painting marks using a bitmap", ioe);
+        } catch (ImageException ie) {
+            throw new IFException(
+                    "Error while painting marks using a bitmap", ie);
+        }
     }
 
     /** [EMAIL PROTECTED] */
@@ -246,8 +317,6 @@
             }
         } catch (IOException ioe) {
             throw new IFException("I/O error in drawText()", ioe);
-        } catch (ImageException ime) {
-            throw new IFException("Image processing error in drawText()", ime);
         }
     }
 
@@ -304,7 +373,7 @@
 
     private static final double SAFETY_MARGIN_FACTOR = 0.05;
 
-    private Rectangle getTextBoundingRect(int x, int y, int[] dx, int[] dy, 
String text,
+    private Rectangle getTextBoundingBox(int x, int y, int[] dx, int[] dy, 
String text,
             Font font, FontMetricsMapper metrics) {
         int maxAscent = metrics.getMaxAscent(font.getFontSize()) / 1000;
         int descent = metrics.getDescender(font.getFontSize()) / 1000; //is 
negative
@@ -339,11 +408,9 @@
     }
 
     private void drawTextAsBitmap(final int x, final int y, final int[] dx, 
final int[] dy,
-            final String text, FontTriplet triplet) throws IOException, 
ImageException {
+            final String text, FontTriplet triplet) throws IFException {
         //Use Java2D to paint different fonts via bitmap
         final Font font = parent.getFontInfo().getFontInstance(triplet, 
state.getFontSize());
-        //final Font font = getFontFromArea(text);
-        //final int baseline = text.getBaselineOffset();
 
         //for cursive fonts, so the text isn't clipped
         final FontMetricsMapper mapper = 
(FontMetricsMapper)parent.getFontInfo().getMetricsFor(
@@ -354,14 +421,9 @@
         int safetyMargin = (int)(SAFETY_MARGIN_FACTOR * font.getFontSize());
         final int baselineOffset = maxAscent + safetyMargin;
 
-        final Rectangle boundingRect = getTextBoundingRect(x, y, dx, dy, text, 
font, mapper);
-
-        Map atts = new java.util.HashMap();
-        atts.put(CONV_MODE, "bitmap");
-        atts.put(SRC_TRANSPARENCY, "true");
-        //rc.setProperty(RendererContextConstants.FOREIGN_ATTRIBUTES, atts);
+        final Rectangle boundingBox = getTextBoundingBox(x, y, dx, dy, text, 
font, mapper);
+        final Dimension dim = boundingBox.getSize();
 
-        final Dimension dim = boundingRect.getSize();
         Graphics2DImagePainter painter = new Graphics2DImagePainter() {
 
             public void paint(Graphics2D g2d, Rectangle2D area) {
@@ -394,19 +456,7 @@
             }
 
         };
-        ImageInfo info = new ImageInfo(null, null);
-        ImageSize size = new ImageSize();
-        size.setSizeInMillipoints(boundingRect.width, boundingRect.height);
-        info.setSize(size);
-        ImageGraphics2D img = new ImageGraphics2D(info, painter);
-
-        Rectangle rect = boundingRect;
-        Map hints = new java.util.HashMap();
-        hints.put(ImageProcessingHints.BITMAP_TYPE_INTENT,
-                ImageProcessingHints.BITMAP_TYPE_INTENT_GRAY);
-        PCLRenderingContext context = 
(PCLRenderingContext)createRenderingContext();
-        context.setSourceTransparencyEnabled(true);
-        drawImage(img, rect, context, true, hints);
+        paintMarksAsBitmap(painter, boundingBox);
     }
 
     /** Saves the current graphics state on the stack. */

Modified: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderer.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderer.java?rev=709119&r1=709118&r2=709119&view=diff
==============================================================================
--- 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderer.java
 (original)
+++ 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderer.java
 Thu Oct 30 01:49:44 2008
@@ -164,7 +164,8 @@
      * @param qualityBeforeSpeed true if quality is more important than speed
      */
     public void setQualityBeforeSpeed(boolean qualityBeforeSpeed) {
-        pclUtil.setQualityBeforeSpeed(qualityBeforeSpeed);
+        pclUtil.setRenderingMode(qualityBeforeSpeed
+                ? PCLRenderingMode.QUALITY : PCLRenderingMode.SPEED);
     }
 
     /**
@@ -1187,10 +1188,10 @@
         if (bpsBefore == null && bpsAfter == null && bpsStart == null && 
bpsEnd == null) {
             return; //no borders to paint
         }
-        if (pclUtil.isQualityBeforeSpeed()) {
-            drawQualityBorders(borderRect, bpsBefore, bpsAfter, bpsStart, 
bpsEnd);
-        } else {
+        if (PCLRenderingMode.SPEED == pclUtil.getRenderingMode()) {
             drawFastBorders(borderRect, bpsBefore, bpsAfter, bpsStart, bpsEnd);
+        } else {
+            drawQualityBorders(borderRect, bpsBefore, bpsAfter, bpsStart, 
bpsEnd);
         }
     }
 

Modified: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java?rev=709119&r1=709118&r2=709119&view=diff
==============================================================================
--- 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
 (original)
+++ 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
 Thu Oct 30 01:49:44 2008
@@ -75,13 +75,11 @@
 
     private void configure(Configuration cfg, PCLRenderingUtil pclUtil) throws 
FOPException {
         String rendering = cfg.getChild("rendering").getValue(null);
-        if ("quality".equalsIgnoreCase(rendering)) {
-            pclUtil.setQualityBeforeSpeed(true);
-        } else if ("speed".equalsIgnoreCase(rendering)) {
-            pclUtil.setQualityBeforeSpeed(false);
-        } else if (rendering != null) {
+        try {
+            pclUtil.setRenderingMode(PCLRenderingMode.valueOf(rendering));
+        } catch (IllegalArgumentException e) {
             throw new FOPException(
-                    "Valid values for 'rendering' are 'quality' and 'speed'. 
Value found: "
+                "Valid values for 'rendering' are 'quality', 'speed' and 
'bitmap'. Value found: "
                         + rendering);
         }
 

Added: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java?rev=709119&view=auto
==============================================================================
--- 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java
 (added)
+++ 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java
 Thu Oct 30 01:49:44 2008
@@ -0,0 +1,82 @@
+/*
+ * 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.pcl;
+
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+
+/**
+ * Enumeration class for PCL rendering modes.
+ */
+public final class PCLRenderingMode implements Serializable {
+
+    private static final long serialVersionUID = 6359884255324755026L;
+
+    /** "Quality" rendering (mixed native and bitmap for improved quality) */
+    public static final PCLRenderingMode QUALITY = new 
PCLRenderingMode("quality");
+    /** "Speed" rendering (maximum speed with native rendering, reduced visual 
quality) */
+    public static final PCLRenderingMode SPEED = new PCLRenderingMode("speed");
+    /**
+     * "Bitmap" rendering (pages are painted entirely as bitmaps, maximum 
quality,
+     * reduced performance)
+     */
+    public static final PCLRenderingMode BITMAP = new 
PCLRenderingMode("bitmap");
+
+    private String name;
+
+    /**
+     * Constructor to add a new named item.
+     * @param name Name of the item.
+     */
+    private PCLRenderingMode(String name) {
+        this.name = name;
+    }
+
+    /** @return the name of the enum */
+    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 PCLRenderingMode valueOf(String name) {
+        if (QUALITY.getName().equalsIgnoreCase(name)) {
+            return QUALITY;
+        } else if (SPEED.getName().equalsIgnoreCase(name)) {
+            return SPEED;
+        } else if (BITMAP.getName().equalsIgnoreCase(name)) {
+            return BITMAP;
+        } else {
+            throw new IllegalArgumentException("Illegal value for enumeration: 
" + name);
+        }
+    }
+
+    private Object readResolve() throws ObjectStreamException {
+        return valueOf(getName());
+    }
+
+    /** [EMAIL PROTECTED] */
+    public String toString() {
+        return "PCLRenderingMode:" + name;
+    }
+}

Propchange: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java?rev=709119&r1=709118&r2=709119&view=diff
==============================================================================
--- 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java
 (original)
+++ 
xmlgraphics/fop/branches/Temp_AreaTreeNewDesign/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java
 Thu Oct 30 01:49:44 2008
@@ -42,10 +42,10 @@
     private FOUserAgent userAgent;
 
     /**
-     * Controls whether appearance is more important than speed. False can 
cause some FO feature
+     * Controls whether appearance is more important than speed. "SPEED" can 
cause some FO feature
      * to be ignored (like the advanced borders).
      */
-    private boolean qualityBeforeSpeed = false;
+    private PCLRenderingMode renderingMode = PCLRenderingMode.SPEED;
 
     /**
      * Controls whether all text should be painted as text. This is a fallback 
setting in case
@@ -84,18 +84,18 @@
     /**
      * Configures the renderer to trade speed for quality if desired. One 
example here is the way
      * that borders are rendered.
-     * @param qualityBeforeSpeed true if quality is more important than speed
+     * @param mode one of the [EMAIL PROTECTED] PCLRenderingMode}.* constants
      */
-    public void setQualityBeforeSpeed(boolean qualityBeforeSpeed) {
-        this.qualityBeforeSpeed = qualityBeforeSpeed;
+    public void setRenderingMode(PCLRenderingMode mode) {
+        this.renderingMode = mode;
     }
 
     /**
-     * Indicates whether quality is more important than speed.
-     * @return true if quality is favored over speed
+     * Returns the selected rendering mode.
+     * @return the rendering mode
      */
-    public boolean isQualityBeforeSpeed() {
-        return this.qualityBeforeSpeed;
+    public PCLRenderingMode getRenderingMode() {
+        return this.renderingMode;
     }
 
     /**



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to