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/04/28 10:51:31 UTC

svn commit: r397806 [2/2] - in /xmlgraphics/fop/trunk: src/java/META-INF/services/ src/java/org/apache/fop/apps/ src/java/org/apache/fop/area/ src/java/org/apache/fop/fo/ src/java/org/apache/fop/fo/extensions/ src/java/org/apache/fop/layoutmgr/ src/jav...

Added: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLPageDefinition.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLPageDefinition.java?rev=397806&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLPageDefinition.java (added)
+++ xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLPageDefinition.java Fri Apr 28 01:51:27 2006
@@ -0,0 +1,143 @@
+/*
+ * 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.pcl;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.fop.util.UnitConv;
+
+/**
+ * This class represents a page format with PCL-specific properties.
+ */
+public class PCLPageDefinition {
+
+    private static List pageDefinitions;
+    
+    private String name;
+    private long width; //in mpt
+    private long height; //in mpt
+    private int logicalPageXOffset; //in mpt
+    private boolean landscape;
+    
+    static {
+        createPageDefinitions();
+    }
+    
+    public PCLPageDefinition(String name, long width, long height, int logicalPageXOffset) {
+        this(name, width, height, logicalPageXOffset, false);
+    }
+    
+    public PCLPageDefinition(String name, long width, long height, int logicalPageXOffset, 
+            boolean landscape) {
+        this.name = name;
+        this.width = width;
+        this.height = height;
+        this.logicalPageXOffset = logicalPageXOffset;
+        this.landscape = landscape;
+    }
+    
+    public String getName() {
+        return this.name;
+    }
+    
+    public boolean isLandscapeFormat() {
+        return this.landscape;
+    }
+    
+    public int getLogicalPageXOffset() {
+        return this.logicalPageXOffset;
+    }
+    
+    public boolean matches(long width, long height, int errorMargin) {
+        return (Math.abs(this.width - width) < errorMargin) 
+            && (Math.abs(this.height - height) < errorMargin);
+    }
+    
+    /** @see java.lang.Object#toString() */
+    public String toString() {
+        return getName();
+    }
+
+    public static PCLPageDefinition getPageDefinition(long width, long height, int errorMargin) {
+        Iterator iter = pageDefinitions.iterator();
+        while (iter.hasNext()) {
+            PCLPageDefinition def = (PCLPageDefinition)iter.next();
+            if (def.matches(width, height, errorMargin)) {
+                return def;
+            }
+        }
+        return null;
+    }
+    
+    /**
+     * Converts an offset values for logical pages to millipoints. The values are given as pixels
+     * in a 300dpi environment.
+     * @param offset the offset as given in the PCL 5 specification (under "Printable Area")
+     * @return the converted value in millipoints
+     */
+    private static int convertLogicalPageXOffset(int offset) {
+        return (int)Math.round(((double)offset) * 72000 / 300);
+    }
+    
+    private static void createPageDefinitions() {
+        pageDefinitions = new java.util.ArrayList();
+        pageDefinitions.add(new PCLPageDefinition("Letter", 
+                Math.round(UnitConv.in2mpt(8.5)), Math.round(UnitConv.in2mpt(11)),
+                convertLogicalPageXOffset(75)));
+        pageDefinitions.add(new PCLPageDefinition("Legal", 
+                Math.round(UnitConv.in2mpt(8.5)), Math.round(UnitConv.in2mpt(14)),
+                convertLogicalPageXOffset(75)));
+        pageDefinitions.add(new PCLPageDefinition("Executive", 
+                Math.round(UnitConv.in2mpt(7.25)), Math.round(UnitConv.in2mpt(10.5)),
+                convertLogicalPageXOffset(75)));
+        pageDefinitions.add(new PCLPageDefinition("Ledger", 
+                Math.round(UnitConv.in2mpt(11)), Math.round(UnitConv.in2mpt(17)),
+                convertLogicalPageXOffset(75)));
+        pageDefinitions.add(new PCLPageDefinition("A4", 
+                Math.round(UnitConv.mm2mpt(210)), Math.round(UnitConv.mm2mpt(297)),
+                convertLogicalPageXOffset(71)));
+        pageDefinitions.add(new PCLPageDefinition("A3", 
+                Math.round(UnitConv.mm2mpt(297)), Math.round(UnitConv.mm2mpt(420)),
+                convertLogicalPageXOffset(71)));
+
+        //TODO Add envelope definitions
+        
+        pageDefinitions.add(new PCLPageDefinition("LetterL", 
+                Math.round(UnitConv.in2mpt(11)), Math.round(UnitConv.in2mpt(8.5)),
+                convertLogicalPageXOffset(60)));
+        pageDefinitions.add(new PCLPageDefinition("LegalL", 
+                Math.round(UnitConv.in2mpt(14)), Math.round(UnitConv.in2mpt(8.5)),
+                convertLogicalPageXOffset(60)));
+        pageDefinitions.add(new PCLPageDefinition("ExecutiveL", 
+                Math.round(UnitConv.in2mpt(10.5)), Math.round(UnitConv.in2mpt(7.25)),
+                convertLogicalPageXOffset(60)));
+        pageDefinitions.add(new PCLPageDefinition("LedgerL", 
+                Math.round(UnitConv.in2mpt(17)), Math.round(UnitConv.in2mpt(11)),
+                convertLogicalPageXOffset(60)));
+        pageDefinitions.add(new PCLPageDefinition("A4L", 
+                Math.round(UnitConv.mm2mpt(297)), Math.round(UnitConv.mm2mpt(210)),
+                convertLogicalPageXOffset(59), true));
+        pageDefinitions.add(new PCLPageDefinition("A3L", 
+                Math.round(UnitConv.mm2mpt(420)), Math.round(UnitConv.mm2mpt(297)),
+                convertLogicalPageXOffset(59)));
+    }
+
+    
+}

Propchange: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLPageDefinition.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLRenderer.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLRenderer.java?rev=397806&r1=397805&r2=397806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLRenderer.java (original)
+++ xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLRenderer.java Fri Apr 28 01:51:27 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-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.
@@ -19,53 +19,109 @@
 package org.apache.fop.render.pcl;
 
 // FOP
+import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.area.Area;
+import org.apache.fop.area.Block;
+import org.apache.fop.area.BlockViewport;
 import org.apache.fop.area.CTM;
+import org.apache.fop.area.PageViewport;
+import org.apache.fop.area.Trait;
+import org.apache.fop.area.Trait.Color;
+import org.apache.fop.area.inline.AbstractTextArea;
+import org.apache.fop.area.inline.ForeignObject;
+import org.apache.fop.area.inline.Image;
+import org.apache.fop.area.inline.SpaceArea;
+import org.apache.fop.area.inline.TextArea;
+import org.apache.fop.area.inline.Viewport;
+import org.apache.fop.area.inline.WordArea;
+import org.apache.fop.fonts.Font;
+import org.apache.fop.image.EPSImage;
+import org.apache.fop.image.FopImage;
+import org.apache.fop.image.ImageFactory;
+import org.apache.fop.image.XMLImage;
+import org.apache.fop.render.Graphics2DAdapter;
 import org.apache.fop.render.PrintRenderer;
+import org.apache.fop.render.RendererContext;
+import org.apache.fop.render.RendererContextConstants;
+import org.apache.fop.traits.BorderProps;
+import org.apache.xmlgraphics.java2d.GraphicContext;
+import org.w3c.dom.Document;
 
 // Java
+import java.awt.Rectangle;
+import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.PixelInterleavedSampleModel;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
 
 /**
- * Renderer that renders areas to PCL
- * Created by Arthur E Welch III while at M&I EastPoint Technology
- * Donated by EastPoint to the Apache FOP project March 2, 2001.
+ * Renderer for the PCL 5 printer language. It also uses HP GL/2 for certain graphic elements.
  */
 public class PCLRenderer extends PrintRenderer {
 
     /** The MIME type for PCL */
     public static final String MIME_TYPE = MimeConstants.MIME_PCL_ALT;
 
+    /** The OutputStream to write the PCL stream to */
+    protected OutputStream out;
+    
+    /** The PCL generator */
+    protected PCLGenerator gen;
+    private boolean ioTrouble = false;
+
+    private Stack graphicContextStack = new Stack();
+    private GraphicContext graphicContext = new GraphicContext();
+    
     /**
-     * the current stream to add PCL commands to
+     * Create the PCL renderer
      */
-    protected PCLStream currentStream;
-
-    private int pageHeight = 7920;
-
-    // These variables control the virtual paggination functionality.
-    private int curdiv = 0;
-    private int divisions = -1;
-    private int paperheight = -1;    // Paper height in decipoints?
-    private int orientation = -1;    // -1=default/unknown, 0=portrait, 1=landscape.
-    private int topmargin = -1;      // Top margin in decipoints?
-    private int leftmargin = -1;     // Left margin in decipoints?
-    private int fullmargin = 0;
-    private final boolean debug = false;
-
-    private int xoffset = -180;     // X Offset to allow for PCL implicit 1/4" left margin.
-
-    private java.util.Hashtable options;
+    public PCLRenderer() {
+    }
 
     /**
-     * Create the PCL renderer
+     * Central exception handler for I/O exceptions.
+     * @param ioe IOException to handle
      */
-    public PCLRenderer() {
+    protected void handleIOTrouble(IOException ioe) {
+        if (!ioTrouble) {
+            log.error("Error while writing to target file", ioe);
+            ioTrouble = true;
+        }
+    }
+
+    /** @see org.apache.fop.render.Renderer#getGraphics2DAdapter() */
+    public Graphics2DAdapter getGraphics2DAdapter() {
+        return new PCLGraphics2DAdapter();
     }
 
-    public void setFont(String name, float size) {
+    /** @return the GraphicContext used to track coordinate system transformations */
+    public GraphicContext getGraphicContext() {
+        return this.graphicContext;
+    }
+    
+    /**
+     * Sets the current font (NOTE: Hard-coded font mappings ATM!)
+     * @param name the font name (internal F* names for now)
+     * @param size the font size
+     * @throws IOException if an I/O problem occurs
+     */
+    public void setFont(String name, float size) throws IOException {
         int fontcode = 0;
         if (name.length() > 1 && name.charAt(0) == 'F') {
             try {
@@ -74,113 +130,113 @@
                 log.error(e);
             }
         }
+        String formattedSize = gen.formatDouble2(size / 1000);
         switch (fontcode) {
         case 1:     // F1 = Helvetica
-            // currentStream.add("\033(8U\033(s1p" + (size / 1000) + "v0s0b24580T");
+            // gen.writeCommand("(8U");
+            // gen.writeCommand("(s1p" + formattedSize + "v0s0b24580T");
             // Arial is more common among PCL5 printers than Helvetica - so use Arial
 
-            currentStream.add("\033(0N\033(s1p" + (size / 1000)
-                              + "v0s0b16602T");
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s1p" + formattedSize + "v0s0b16602T");
             break;
         case 2:     // F2 = Helvetica Oblique
 
-            currentStream.add("\033(0N\033(s1p" + (size / 1000)
-                              + "v1s0b16602T");
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s1p" + formattedSize + "v1s0b16602T");
             break;
         case 3:     // F3 = Helvetica Bold
 
-            currentStream.add("\033(0N\033(s1p" + (size / 1000)
-                              + "v0s3b16602T");
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s1p" + formattedSize + "v0s3b16602T");
             break;
         case 4:     // F4 = Helvetica Bold Oblique
 
-            currentStream.add("\033(0N\033(s1p" + (size / 1000)
-                              + "v1s3b16602T");
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s1p" + formattedSize + "v1s3b16602T");
             break;
         case 5:     // F5 = Times Roman
-            // currentStream.add("\033(8U\033(s1p" + (size / 1000) + "v0s0b25093T");
+            // gen.writeCommand("(8U");
+            // gen.writeCommand("(s1p" + formattedSize + "v0s0b25093T");
             // Times New is more common among PCL5 printers than Times - so use Times New
 
-            currentStream.add("\033(0N\033(s1p" + (size / 1000)
-                              + "v0s0b16901T");
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s1p" + formattedSize + "v0s0b16901T");
             break;
         case 6:     // F6 = Times Italic
 
-            currentStream.add("\033(0N\033(s1p" + (size / 1000)
-                              + "v1s0b16901T");
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s1p" + formattedSize + "v1s0b16901T");
             break;
         case 7:     // F7 = Times Bold
 
-            currentStream.add("\033(0N\033(s1p" + (size / 1000)
-                              + "v0s3b16901T");
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s1p" + formattedSize + "v0s3b16901T");
             break;
         case 8:     // F8 = Times Bold Italic
 
-            currentStream.add("\033(0N\033(s1p" + (size / 1000)
-                              + "v1s3b16901T");
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s1p" + formattedSize + "v1s3b16901T");
             break;
         case 9:     // F9 = Courier
 
-            currentStream.add("\033(0N\033(s0p"
-                              + (120.01f / (size / 1000.00f)) + "h0s0b4099T");
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s0p" + gen.formatDouble2(120.01f / (size / 1000.00f)) 
+                    + "h0s0b4099T");
             break;
         case 10:    // F10 = Courier Oblique
 
-            currentStream.add("\033(0N\033(s0p"
-                              + (120.01f / (size / 1000.00f)) + "h1s0b4099T");
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s0p" + gen.formatDouble2(120.01f / (size / 1000.00f)) 
+                    + "h1s0b4099T");
             break;
         case 11:    // F11 = Courier Bold
 
-            currentStream.add("\033(0N\033(s0p"
-                              + (120.01f / (size / 1000.00f)) + "h0s3b4099T");
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s0p" + gen.formatDouble2(120.01f / (size / 1000.00f)) 
+                    + "h0s3b4099T");
             break;
         case 12:    // F12 = Courier Bold Oblique
 
-            currentStream.add("\033(0N\033(s0p"
-                              + (120.01f / (size / 1000.00f)) + "h1s3b4099T");
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s0p" + gen.formatDouble2(120.01f / (size / 1000.00f)) 
+                    + "h1s3b4099T");
             break;
         case 13:    // F13 = Symbol
 
-            currentStream.add("\033(19M\033(s1p" + (size / 1000)
-                              + "v0s0b16686T");
+            gen.writeCommand("(19M");
+            gen.writeCommand("(s1p" + formattedSize + "v0s0b16686T");
             // ECMA Latin 1 Symbol Set in Times Roman???
-            // currentStream.add("\033(9U\033(s1p" + (size / 1000) + "v0s0b25093T");
+            // gen.writeCommand("(9U");
+            // gen.writeCommand("(s1p" + formattedSize + "v0s0b25093T");
             break;
         case 14:    // F14 = Zapf Dingbats
 
-            currentStream.add("\033(14L\033(s1p" + (size / 1000)
-                              + "v0s0b45101T");
+            gen.writeCommand("(14L");
+            gen.writeCommand("(s1p" + formattedSize + "v0s0b45101T");
             break;
         default:
-            currentStream.add("\033(0N\033(s" + (size / 1000) + "V");
+            gen.writeCommand("(0N");
+            gen.writeCommand("(s" + formattedSize + "V");
             break;
         }
     }
 
     /** @see org.apache.fop.render.Renderer#startRenderer(java.io.OutputStream) */
     public void startRenderer(OutputStream outputStream) throws IOException {
-        log.info("rendering areas to PCL");
-        log.fatal("The PCL Renderer is non-functional at this time. Please help resurrect it!");
-        currentStream = new PCLStream(outputStream);
-
-        // Set orientation.
-        if (orientation > -1) {
-            currentStream.add("\033&l" + orientation + "O");
-        } else {
-            currentStream.add("\033&l0O");
-        }
-        if (orientation == 1 || orientation == 3) {
-            xoffset = -144;
-        } else {
-            xoffset = -180;
-        }
+        log.debug("Rendering areas to PCL...");
+        this.out = outputStream;
+        this.gen = new PCLGenerator(out);
 
-        // Reset the margins.
-        currentStream.add("\033" + "9\033&l0E");
+        gen.universalEndOfLanguage();
+        gen.resetPrinter();
     }
 
     /** @see org.apache.fop.render.Renderer#stopRenderer() */
     public void stopRenderer() throws IOException {
+        gen.separateJobs();
+        gen.resetPrinter();
+        gen.universalEndOfLanguage();
     }
 
     /** @see org.apache.fop.render.AbstractRenderer */
@@ -189,17 +245,624 @@
     }
 
     /**
+     * @see org.apache.fop.render.AbstractRenderer#renderPage(org.apache.fop.area.PageViewport)
+     */
+    public void renderPage(PageViewport page) throws IOException, FOPException {
+        saveGraphicsState();
+        final long pagewidth = Math.round(page.getViewArea().getWidth());
+        final long pageheight = Math.round(page.getViewArea().getHeight());
+        selectPageFormat(pagewidth, pageheight);
+        
+        if (false) { //TODO DEBUG CODE! Remove me.
+            //gen.fillRect(0, 0, (int)pagewidth, (int)pageheight, java.awt.Color.yellow);
+            //gen.fillRect(5000, 5000, (int)pagewidth - 10000, (int)pageheight - 10000, java.awt.Color.yellow);
+            //gen.fillRect(10000, 10000, (int)pagewidth / 4 - 20000, (int)pageheight / 4 - 20000, java.awt.Color.red);
+            for (int i = 0; i < 29; i++) {
+                if (i % 2 == 0) {
+                    int w = (int)(10 * 2.835 * 1000);
+                    Point2D p = transformedPoint(i * w, 0);
+                    gen.fillRect((int)p.getX(), (int)p.getY(), w, w, java.awt.Color.yellow);
+                }
+            }
+        }
+        
+        super.renderPage(page);
+        gen.formFeed();
+        restoreGraphicsState();
+    }
+
+    private void selectPageFormat(long pagewidth, long pageheight) throws IOException {
+        
+        PCLPageDefinition pageDef = PCLPageDefinition.getPageDefinition(
+                pagewidth, pageheight, 1000);
+        if (pageDef != null) {
+            // Adjust for the offset into the logical page
+            graphicContext.translate(-pageDef.getLogicalPageXOffset(), 0);
+            if (pageDef.isLandscapeFormat()) {
+                gen.writeCommand("&l1O"); //Orientation
+            } else {
+                gen.writeCommand("&l0O"); //Orientation
+            }
+        } else {
+            // Adjust for the offset into the logical page
+            // X Offset to allow for PCL implicit 1/4" left margin (= 180 decipoints)
+            graphicContext.translate(-18000, 18000);
+            gen.writeCommand("&l0O"); //Orientation
+        }
+        gen.clearHorizontalMargins();
+        gen.setTopMargin(0);
+    }
+
+    /** Saves the current graphics state on the stack. */
+    protected void saveGraphicsState() {
+        graphicContextStack.push(graphicContext);
+        graphicContext = (GraphicContext)graphicContext.clone();
+    }
+
+    /** Restores the last graphics state from the stack. */
+    protected void restoreGraphicsState() {
+        graphicContext = (GraphicContext)graphicContextStack.pop();
+    }
+    
+    /**
+     * Clip an area. write a clipping operation given coordinates in the current
+     * transform. Coordinates are in points.
+     *
+     * @param x the x coordinate
+     * @param y the y coordinate
+     * @param width the width of the area
+     * @param height the height of the area
+     */
+    protected void clipRect(float x, float y, float width, float height) {
+        //PCL cannot clip (only HP GL/2 can)
+    }
+
+    /**
      * @see org.apache.fop.render.AbstractRenderer#startVParea(CTM, Rectangle2D)
      */
     protected void startVParea(CTM ctm, Rectangle2D clippingRect) {
-        // TODO Auto-generated method stub
+        saveGraphicsState();
+        AffineTransform at = new AffineTransform(ctm.toArray());
+        log.debug("startVPArea: " + at);
+        graphicContext.transform(at);
     }
 
     /**
      * @see org.apache.fop.render.AbstractRenderer#endVParea()
      */
     protected void endVParea() {
-        // TODO Auto-generated method stub
+        restoreGraphicsState();
+    }
+
+    /**
+     * Handle block traits.
+     * The block could be any sort of block with any positioning
+     * so this should render the traits such as border and background
+     * in its position.
+     *
+     * @param block the block to render the traits
+     */
+    protected void handleBlockTraits(Block block) {
+        int borderPaddingStart = block.getBorderAndPaddingWidthStart();
+        int borderPaddingBefore = block.getBorderAndPaddingWidthBefore();
+        
+        float startx = currentIPPosition / 1000f;
+        float starty = currentBPPosition / 1000f;
+        float width = block.getIPD() / 1000f;
+        float height = block.getBPD() / 1000f;
+
+        startx += block.getStartIndent() / 1000f;
+        startx -= block.getBorderAndPaddingWidthStart() / 1000f;
+
+        width += borderPaddingStart / 1000f;
+        width += block.getBorderAndPaddingWidthEnd() / 1000f;
+        height += borderPaddingBefore / 1000f;
+        height += block.getBorderAndPaddingWidthAfter() / 1000f;
+
+        drawBackAndBorders(block, startx, starty, width, height);
+    }
+
+    /**
+     * @see org.apache.fop.render.AbstractRenderer#renderText(TextArea)
+     */
+    protected void renderText(TextArea area) {
+        //renderInlineAreaBackAndBorders(area);
+        String fontname = getInternalFontNameForArea(area);
+        int fontsize = area.getTraitAsInteger(Trait.FONT_SIZE);
+
+        //Determine position
+        //int saveIP = currentIPPosition;
+        //int saveBP = currentBPPosition;
+        int rx = currentIPPosition + area.getBorderAndPaddingWidthStart();
+        int bl = currentBPPosition + area.getOffset() + area.getBaselineOffset();
+
+        try {
+            setFont(fontname, fontsize);
+            Color col = (Color)area.getTrait(Trait.COLOR);
+            //this.currentFill = col;
+            if (col != null) {
+                //useColor(ct);
+                gen.setPatternTransparencyMode(false);
+                gen.selectCurrentPattern(gen.convertToPCLShade(col.getAWTColor()), 2);
+            }
+            
+            saveGraphicsState();
+            updatePrintDirection();
+            graphicContext.translate(rx, bl);
+            moveTo(0, 0);
+        
+            super.renderText(area); //Updates IPD
+        
+            //renderTextDecoration(tf, fontsize, area, bl, rx);
+            restoreGraphicsState();
+        } catch (IOException ioe) {
+            handleIOTrouble(ioe);
+        }
+    }
+
+    void moveTo(int x, int y) throws IOException {
+        Point2D transPoint = transformedPoint(x, y);
+        gen.writeCommand("&a" + gen.formatDouble2(transPoint.getX() / 100) + "h" 
+                + gen.formatDouble2(transPoint.getY() / 100) + "V");
+    }
+
+    private void updatePrintDirection() throws IOException {
+        AffineTransform at = graphicContext.getTransform();
+        if (log.isDebugEnabled()) {
+            log.debug(at.getScaleX() + " " + at.getScaleY() + " " 
+                    + at.getShearX() + " " + at.getShearY() );
+        }
+        if (at.getScaleX() == 0 && at.getScaleY() == 0 
+                && at.getShearX() == 1 && at.getShearY() == -1) {
+            gen.writeCommand("&a90P");
+        } else if (at.getScaleX() == -1 && at.getScaleY() == -1 
+                && at.getShearX() == 0 && at.getShearY() == 0) {
+            gen.writeCommand("&a180P");
+        } else if (at.getScaleX() == 0 && at.getScaleY() == 0 
+                && at.getShearX() == -1 && at.getShearY() == 1) {
+            gen.writeCommand("&a270P");
+        } else {
+            gen.writeCommand("&a0P");
+        }
+    }
+
+    private Point2D transformedPoint(float x, float y) {
+        return transformedPoint(Math.round(x), Math.round(y));
+    }
+    
+    private Point2D transformedPoint(int x, int y) {
+        AffineTransform at = graphicContext.getTransform();
+        if (log.isDebugEnabled()) {
+            log.debug("Current transform: " + at);
+        }
+        Point2D orgPoint = new Point2D.Float(x, y);
+        Point2D transPoint = new Point2D.Float();
+        at.transform(orgPoint, transPoint);
+        return transPoint;
+    }
+    
+    /**
+     * @see org.apache.fop.render.AbstractRenderer#renderWord(org.apache.fop.area.inline.WordArea)
+     */
+    protected void renderWord(WordArea word) {
+        //Font font = getFontFromArea(word.getParentArea());
+
+        String s = word.getWord();
+
+        try {
+            gen.writeText(s);
+        } catch (IOException ioe) {
+            handleIOTrouble(ioe);
+        }
+
+        super.renderWord(word);
+    }
+
+    /**
+     * @see org.apache.fop.render.AbstractRenderer#renderSpace(org.apache.fop.area.inline.SpaceArea)
+     */
+    protected void renderSpace(SpaceArea space) {
+        AbstractTextArea textArea = (AbstractTextArea)space.getParentArea();
+        String s = space.getSpace();
+        char sp = s.charAt(0);
+        Font font = getFontFromArea(textArea);
+        
+        int tws = (space.isAdjustable() 
+                ? ((TextArea) space.getParentArea()).getTextWordSpaceAdjust() 
+                        + 2 * textArea.getTextLetterSpaceAdjust()
+                : 0);
+
+        double dx = (font.getCharWidth(sp) + tws) / 100f;
+        try {
+            gen.writeCommand("&a+" + gen.formatDouble2(dx) + "H");
+        } catch (IOException ioe) {
+            handleIOTrouble(ioe);
+        }
+        super.renderSpace(space);
+    }
+
+    /**
+     * @see org.apache.fop.render.AbstractRenderer#renderViewport(org.apache.fop.area.inline.Viewport)
+     */
+    public void renderViewport(Viewport viewport) {
+
+        float x = currentIPPosition / 1000f;
+        float y = (currentBPPosition + viewport.getOffset()) / 1000f;
+        float width = viewport.getIPD() / 1000f;
+        float height = viewport.getBPD() / 1000f;
+        // TODO: Calculate the border rect correctly. 
+        float borderPaddingStart = viewport.getBorderAndPaddingWidthStart() / 1000f;
+        float borderPaddingBefore = viewport.getBorderAndPaddingWidthBefore() / 1000f;
+        float bpwidth = borderPaddingStart 
+                + (viewport.getBorderAndPaddingWidthEnd() / 1000f);
+        float bpheight = borderPaddingBefore
+                + (viewport.getBorderAndPaddingWidthAfter() / 1000f);
+
+        drawBackAndBorders(viewport, x, y, width + bpwidth, height + bpheight);
+
+        if (viewport.getClip()) {
+            saveGraphicsState();
+
+            clipRect(x + borderPaddingStart, y + borderPaddingBefore, width, height);
+        }
+        super.renderViewport(viewport);
+
+        if (viewport.getClip()) {
+            restoreGraphicsState();
+        }
+    }
+
+    /**
+     * @see org.apache.fop.render.AbstractRenderer#renderBlockViewport(BlockViewport, List)
+     */
+    protected void renderBlockViewport(BlockViewport bv, List children) {
+        // clip and position viewport if necessary
+
+        // save positions
+        int saveIP = currentIPPosition;
+        int saveBP = currentBPPosition;
+        //String saveFontName = currentFontName;
+
+        CTM ctm = bv.getCTM();
+        int borderPaddingStart = bv.getBorderAndPaddingWidthStart();
+        int borderPaddingBefore = bv.getBorderAndPaddingWidthBefore();
+        float x, y;
+        x = (float)(bv.getXOffset() + containingIPPosition) / 1000f;
+        y = (float)(bv.getYOffset() + containingBPPosition) / 1000f;
+        //This is the content-rect
+        float width = (float)bv.getIPD() / 1000f;
+        float height = (float)bv.getBPD() / 1000f;
+        
+
+        if (bv.getPositioning() == Block.ABSOLUTE
+                || bv.getPositioning() == Block.FIXED) {
+
+            currentIPPosition = bv.getXOffset();
+            currentBPPosition = bv.getYOffset();
+
+            //For FIXED, we need to break out of the current viewports to the
+            //one established by the page. We save the state stack for restoration
+            //after the block-container has been painted. See below.
+            List breakOutList = null;
+            if (bv.getPositioning() == Block.FIXED) {
+                //breakOutList = breakOutOfStateStack();
+            }
+            
+            CTM tempctm = new CTM(containingIPPosition, containingBPPosition);
+            ctm = tempctm.multiply(ctm);
+
+            //Adjust for spaces (from margin or indirectly by start-indent etc.
+            x += bv.getSpaceStart() / 1000f;
+            currentIPPosition += bv.getSpaceStart();
+            
+            y += bv.getSpaceBefore() / 1000f;
+            currentBPPosition += bv.getSpaceBefore(); 
+
+            float bpwidth = (borderPaddingStart + bv.getBorderAndPaddingWidthEnd()) / 1000f;
+            float bpheight = (borderPaddingBefore + bv.getBorderAndPaddingWidthAfter()) / 1000f;
+
+            drawBackAndBorders(bv, x, y, width + bpwidth, height + bpheight);
+
+            //Now adjust for border/padding
+            currentIPPosition += borderPaddingStart;
+            currentBPPosition += borderPaddingBefore;
+            
+            Rectangle2D clippingRect = null;
+            if (bv.getClip()) {
+                clippingRect = new Rectangle(currentIPPosition, currentBPPosition, 
+                        bv.getIPD(), bv.getBPD());
+            }
+
+            startVParea(ctm, clippingRect);
+            currentIPPosition = 0;
+            currentBPPosition = 0;
+            renderBlocks(bv, children);
+            endVParea();
+
+            if (breakOutList != null) {
+                //restoreStateStackAfterBreakOut(breakOutList);
+            }
+            
+            currentIPPosition = saveIP;
+            currentBPPosition = saveBP;
+        } else {
+
+            currentBPPosition += bv.getSpaceBefore();
+
+            //borders and background in the old coordinate system
+            handleBlockTraits(bv);
+
+            //Advance to start of content area
+            currentIPPosition += bv.getStartIndent();
+
+            CTM tempctm = new CTM(containingIPPosition, currentBPPosition);
+            ctm = tempctm.multiply(ctm);
+            
+            //Now adjust for border/padding
+            currentBPPosition += borderPaddingBefore;
+
+            Rectangle2D clippingRect = null;
+            if (bv.getClip()) {
+                clippingRect = new Rectangle(currentIPPosition, currentBPPosition, 
+                        bv.getIPD(), bv.getBPD());
+            }
+            
+            startVParea(ctm, clippingRect);
+            currentIPPosition = 0;
+            currentBPPosition = 0;
+            renderBlocks(bv, children);
+            endVParea();
+
+            currentIPPosition = saveIP;
+            currentBPPosition = saveBP;
+            
+            currentBPPosition += (int)(bv.getAllocBPD());
+        }
+        //currentFontName = saveFontName;
+    }
+
+    /**
+     * @see org.apache.fop.render.AbstractRenderer#renderImage(Image, Rectangle2D)
+     */
+    public void renderImage(Image image, Rectangle2D pos) {
+        String url = ImageFactory.getURL(image.getURL());
+        ImageFactory fact = userAgent.getFactory().getImageFactory();
+        FopImage fopimage = fact.getImage(url, userAgent);
+        if (fopimage == null) {
+            return;
+        }
+        if (!fopimage.load(FopImage.DIMENSIONS)) {
+            return;
+        }
+        String mime = fopimage.getMimeType();
+        if ("text/xml".equals(mime)) {
+            if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
+                return;
+            }
+            Document doc = ((XMLImage) fopimage).getDocument();
+            String ns = ((XMLImage) fopimage).getNameSpace();
+
+            renderDocument(doc, ns, pos, image.getForeignAttributes());
+        } else if ("image/svg+xml".equals(mime)) {
+            if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
+                return;
+            }
+            Document doc = ((XMLImage) fopimage).getDocument();
+            String ns = ((XMLImage) fopimage).getNameSpace();
+
+            renderDocument(doc, ns, pos, image.getForeignAttributes());
+        } else if (fopimage instanceof EPSImage) {
+            log.warn("EPS images are not supported by this renderer");
+        } else {
+            if (!fopimage.load(FopImage.BITMAP)) {
+                log.error("Bitmap image could not be processed: " + fopimage);
+                return;
+            }
+            byte[] imgmap = fopimage.getBitmaps();
+            
+            ColorModel cm = new ComponentColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB), 
+                    new int[] {8, 8, 8},
+                    false, false,
+                    ColorModel.OPAQUE, DataBuffer.TYPE_BYTE);
+            int imgw = fopimage.getWidth();
+            int imgh = fopimage.getHeight();
+            SampleModel sampleModel = new PixelInterleavedSampleModel(
+                    DataBuffer.TYPE_BYTE, imgw, imgh, 3, imgw * 3, new int[] {0, 1, 2});
+            DataBuffer dbuf = new DataBufferByte(imgmap, imgw * imgh * 3);
+
+            WritableRaster raster = Raster.createWritableRaster(sampleModel,
+                    dbuf, null);
+
+            // Combine the color model and raster into a buffered image
+            RenderedImage img = new BufferedImage(cm, raster, false, null);
+
+            try {
+                moveTo(this.currentIPPosition + (int)pos.getX(),
+                        this.currentBPPosition + (int)pos.getY());
+                int resolution = (int)Math.round(Math.max(fopimage.getHorizontalResolution(), 
+                                        fopimage.getVerticalResolution()));
+                gen.paintBitmap(img, resolution);
+            } catch (IOException ioe) {
+                handleIOTrouble(ioe);
+            }
+        }
+    }
+
+    /**
+     * @see org.apache.fop.render.AbstractRenderer#renderForeignObject(ForeignObject, Rectangle2D)
+     */
+    public void renderForeignObject(ForeignObject fo, Rectangle2D pos) {
+        Document doc = fo.getDocument();
+        String ns = fo.getNameSpace();
+        renderDocument(doc, ns, pos, fo.getForeignAttributes());
+    }
+
+    /**
+     * Renders an XML document (SVG for example).
+     * @param doc the DOM Document containing the XML document to be rendered
+     * @param ns the namespace URI for the XML document
+     * @param pos the position for the generated graphic/image
+     * @param foreignAttributes the foreign attributes containing rendering hints, or null
+     */
+    public void renderDocument(Document doc, String ns, Rectangle2D pos, Map foreignAttributes) {
+        RendererContext context;
+        context = new RendererContext(this, MIME_TYPE);
+        context.setUserAgent(userAgent);
+
+        context.setProperty(RendererContextConstants.WIDTH,
+                            new Integer((int) pos.getWidth()));
+        context.setProperty(RendererContextConstants.HEIGHT,
+                            new Integer((int) pos.getHeight()));
+        context.setProperty(RendererContextConstants.XPOS,
+                            new Integer(currentIPPosition + (int) pos.getX()));
+        context.setProperty(RendererContextConstants.YPOS,
+                            new Integer(currentBPPosition + (int) pos.getY()));
+        context.setProperty(RendererContextConstants.PAGE_VIEWPORT, 
+                            getCurrentPageViewport());
+        if (foreignAttributes != null) {
+            context.setProperty(RendererContextConstants.FOREIGN_ATTRIBUTES, foreignAttributes);
+        }
+        
+        renderXML(context, doc, ns);
+    }
+
+    /**
+     * Draw the background and borders. This draws the background and border
+     * traits for an area given the position.
+     *
+     * @param area the area whose traits are used
+     * @param startx the start x position
+     * @param starty the start y position
+     * @param width the width of the area
+     * @param height the height of the area
+     */
+    protected void drawBackAndBorders(Area area, float startx, float starty,
+            float width, float height) {
+        try {
+            updatePrintDirection();
+            BorderProps bpsBefore = (BorderProps) area.getTrait(Trait.BORDER_BEFORE);
+        BorderProps bpsAfter = (BorderProps) area.getTrait(Trait.BORDER_AFTER);
+        BorderProps bpsStart = (BorderProps) area.getTrait(Trait.BORDER_START);
+        BorderProps bpsEnd = (BorderProps) area.getTrait(Trait.BORDER_END);
+    
+        // draw background
+        Trait.Background back;
+        back = (Trait.Background) area.getTrait(Trait.BACKGROUND);
+        if (back != null) {
+    
+            // Calculate padding rectangle
+            float sx = startx;
+            float sy = starty;
+            float paddRectWidth = width;
+            float paddRectHeight = height;
+    
+            if (bpsStart != null) {
+                sx += bpsStart.width / 1000f;
+                paddRectWidth -= bpsStart.width / 1000f;
+            }
+            if (bpsBefore != null) {
+                sy += bpsBefore.width / 1000f;
+                paddRectHeight -= bpsBefore.width / 1000f;
+            }
+            if (bpsEnd != null) {
+                paddRectWidth -= bpsEnd.width / 1000f;
+            }
+            if (bpsAfter != null) {
+                paddRectHeight -= bpsAfter.width / 1000f;
+            }
+    
+            if (back.getColor() != null) {
+                Point2D p = transformedPoint(sx * 1000, sy * 1000);
+                gen.fillRect((int)p.getX(), (int)p.getY(), 
+                        (int)paddRectWidth * 1000, (int)paddRectHeight * 1000, 
+                        back.getColor().getAWTColor());
+            }
+    
+            // background image
+            if (back.getFopImage() != null) {
+                FopImage fopimage = back.getFopImage();
+                if (fopimage != null && fopimage.load(FopImage.DIMENSIONS)) {
+                    saveGraphicsState();
+                    clipRect(sx, sy, paddRectWidth, paddRectHeight);
+                    int horzCount = (int) ((paddRectWidth * 1000 / fopimage
+                            .getIntrinsicWidth()) + 1.0f);
+                    int vertCount = (int) ((paddRectHeight * 1000 / fopimage
+                            .getIntrinsicHeight()) + 1.0f);
+                    if (back.getRepeat() == EN_NOREPEAT) {
+                        horzCount = 1;
+                        vertCount = 1;
+                    } else if (back.getRepeat() == EN_REPEATX) {
+                        vertCount = 1;
+                    } else if (back.getRepeat() == EN_REPEATY) {
+                        horzCount = 1;
+                    }
+                    // change from points to millipoints
+                    sx *= 1000;
+                    sy *= 1000;
+                    if (horzCount == 1) {
+                        sx += back.getHoriz();
+                    }
+                    if (vertCount == 1) {
+                        sy += back.getVertical();
+                    }
+                    for (int x = 0; x < horzCount; x++) {
+                        for (int y = 0; y < vertCount; y++) {
+                            // place once
+                            Rectangle2D pos;
+                            pos = new Rectangle2D.Float(sx
+                                    + (x * fopimage.getIntrinsicWidth()), sy
+                                    + (y * fopimage.getIntrinsicHeight()),
+                                    fopimage.getIntrinsicWidth(), fopimage
+                                            .getIntrinsicHeight());
+                            //putImage(back.getURL(), pos); // TODO test
+                        }
+                    }
+                    restoreGraphicsState();
+                } else {
+                    log.warn(
+                            "Can't find background image: " + back.getURL());
+                }
+            }
+        }
+/*
+        // draw border
+        // BORDER_BEFORE
+        if (bpsBefore != null) {
+            int borderWidth = (int) Math.round((bpsBefore.width / 1000f));
+            state.updateColor(bpsBefore.color);
+            state.getGraph().fillRect((int) startx, (int) starty, (int) width,
+                    borderWidth);
+        }
+        // BORDER_AFTER
+        if (bpsAfter != null) {
+            int borderWidth = (int) Math.round((bpsAfter.width / 1000f));
+            float sy = starty + height;
+            state.updateColor(bpsAfter.color);
+            state.getGraph().fillRect((int) startx,
+                    (int) (starty + height - borderWidth), (int) width,
+                    borderWidth);
+        }
+        // BORDER_START
+        if (bpsStart != null) {
+            int borderWidth = (int) Math.round((bpsStart.width / 1000f));
+            state.updateColor(bpsStart.color);
+            state.getGraph().fillRect((int) startx, (int) starty, borderWidth,
+                    (int) height);
+        }
+        // BORDER_END
+        if (bpsEnd != null) {
+            int borderWidth = (int) Math.round((bpsEnd.width / 1000f));
+            float sx = startx + width;
+            state.updateColor(bpsEnd.color);
+            state.getGraph().fillRect((int) (startx + width - borderWidth),
+                    (int) starty, borderWidth, (int) height);
+        }
+        */
+        } catch (IOException ioe) {
+            handleIOTrouble(ioe);
+        }
     }
 
+    
 }

Added: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLRendererContext.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLRendererContext.java?rev=397806&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLRendererContext.java (added)
+++ xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLRendererContext.java Fri Apr 28 01:51:27 2006
@@ -0,0 +1,92 @@
+/*
+ * 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.pcl;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.fop.fo.extensions.ExtensionElementMapping;
+import org.apache.fop.render.RendererContext;
+import org.apache.fop.util.QName;
+
+/**
+ * Wrapper on the RendererContext to access the information structure for drawing 
+ * the XML document.
+ */
+public class PCLRendererContext {
+
+    private RendererContext context;
+    
+    /**
+     * Wrap the render context to allow easier access to its values.
+     *
+     * @param context the renderer context
+     * @return the PCL-specific renderer context wrapper
+     */
+    public static PCLRendererContext wrapRendererContext(RendererContext context) {
+        PCLRendererContext pcli = new PCLRendererContext(context);
+        return pcli;
+    }
+
+    /**
+     * Main constructor
+     * @param context the RendererContent instance
+     */
+    public PCLRendererContext(RendererContext context) {
+        this.context = context;
+    }
+    
+    /** @return the currentXPosition */
+    public int getCurrentXPosition() {
+        return ((Integer)context.getProperty(PCLSVGHandler.XPOS)).intValue();
+    }
+
+    /** @return the currentYPosition */
+    public int getCurrentYPosition() {
+        return ((Integer)context.getProperty(PCLSVGHandler.YPOS)).intValue();
+    }
+
+    /** @return the width of the image */
+    public int getWidth() {
+        return ((Integer)context.getProperty(PCLSVGHandler.WIDTH)).intValue();
+    }
+
+    /** @return the height of the image */
+    public int getHeight() {
+        return ((Integer)context.getProperty(PCLSVGHandler.HEIGHT)).intValue();
+    }
+
+    /** @return the handler configuration */
+    public Configuration getHandlerConfiguration() {
+        return (Configuration)context.getProperty(PCLSVGHandler.HANDLER_CONFIGURATION);
+    }
+
+    /** @return the foreign attributes */
+    public Map getForeignAttributes() {
+        return (Map)context.getProperty(PCLSVGHandler.FOREIGN_ATTRIBUTES);
+    }
+    
+    /** @return true if the SVG image should be rendered as a bitmap */
+    public boolean paintAsBitmap() {
+        QName qName = new QName(ExtensionElementMapping.URI, null, "conversion-mode");
+        return getForeignAttributes() != null 
+             && "bitmap".equals(getForeignAttributes().get(qName));
+    }
+
+}
\ No newline at end of file

Propchange: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLRendererContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLSVGHandler.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLSVGHandler.java?rev=397806&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLSVGHandler.java (added)
+++ xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLSVGHandler.java Fri Apr 28 01:51:27 2006
@@ -0,0 +1,144 @@
+/*
+ * 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.pcl;
+
+// Java
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.io.IOException;
+
+// DOM
+import org.w3c.dom.Document;
+
+// Batik
+import org.apache.batik.bridge.GVTBuilder;
+import org.apache.batik.bridge.BridgeContext;
+import org.apache.batik.dom.svg.SVGDOMImplementation;
+import org.apache.batik.gvt.GraphicsNode;
+
+// FOP
+import org.apache.fop.render.Graphics2DAdapter;
+import org.apache.fop.render.Graphics2DImagePainter;
+import org.apache.fop.render.Renderer;
+import org.apache.fop.render.RendererContextConstants;
+import org.apache.fop.render.XMLHandler;
+import org.apache.fop.render.RendererContext;
+import org.apache.fop.svg.SVGUserAgent;
+
+// Commons-Logging
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * PCL XML handler for SVG. Uses Apache Batik for SVG processing.
+ * This handler handles XML for foreign objects when rendering to HP GL/2.
+ * It renders SVG to HP GL/2 using the PCLGraphics2D.
+ *
+ * @version $Id$
+ */
+public class PCLSVGHandler implements XMLHandler, RendererContextConstants {
+
+    /** logging instance */
+    private static Log log = LogFactory.getLog(PCLSVGHandler.class);
+
+    /**
+     * Create a new XML handler for use by the PCL renderer.
+     */
+    public PCLSVGHandler() {
+    }
+
+    /** @see org.apache.fop.render.XMLHandler */
+    public void handleXML(RendererContext context, 
+                Document doc, String ns) throws Exception {
+        PCLRendererContext pclContext = PCLRendererContext.wrapRendererContext(context);
+
+        if (SVGDOMImplementation.SVG_NAMESPACE_URI.equals(ns)) {
+            renderSVGDocument(context, doc, pclContext);
+        }
+    }
+
+    /**
+     * Render the SVG document.
+     * @param context the renderer context
+     * @param doc the SVG document
+     * @param pclContext the information of the current context
+     */
+    protected void renderSVGDocument(final RendererContext context,
+            final Document doc, final PCLRendererContext pclContext) {
+        int x = pclContext.getCurrentXPosition();
+        int y = pclContext.getCurrentYPosition();
+
+        Graphics2DImagePainter painter = new Graphics2DImagePainter() {
+
+            public void paint(Graphics2D g2d, Rectangle2D area) {
+                SVGUserAgent ua = new SVGUserAgent(
+                        context.getUserAgent().getSourcePixelUnitToMillimeter(),
+                        new AffineTransform());
+                GVTBuilder builder = new GVTBuilder();
+                BridgeContext ctx = new BridgeContext(ua);
+
+                GraphicsNode root;
+                try {
+                    root = builder.build(ctx, doc);
+                    
+                    // If no viewbox is defined in the svg file, a viewbox of 100x100 is
+                    // assumed, as defined in SVGUserAgent.getViewportSize()
+                    float iw = (float) ctx.getDocumentSize().getWidth() * 1000f;
+                    float ih = (float) ctx.getDocumentSize().getHeight() * 1000f;
+                    float w = (float) area.getWidth();
+                    float h = (float) area.getHeight();
+                    g2d.scale(w / iw, h / ih);
+
+                    root.paint(g2d);
+                } catch (Exception e) {
+                    log.error("SVG graphic could not be built: "
+                                           + e.getMessage(), e);
+                    return;
+                }
+            }
+
+            public Dimension getImageSize() {
+                return new Dimension(pclContext.getWidth(), pclContext.getHeight());
+            }
+
+        };
+
+        try {
+            Graphics2DAdapter adapter = context.getRenderer().getGraphics2DAdapter();
+            adapter.paintImage(painter, context, 
+                    x, y, pclContext.getWidth(), pclContext.getHeight()); 
+        } catch (IOException ioe) {
+            ((PCLRenderer)context.getRenderer()).handleIOTrouble(ioe);
+        }
+    }
+
+    /** @see org.apache.fop.render.XMLHandler#supportsRenderer(org.apache.fop.render.Renderer) */
+    public boolean supportsRenderer(Renderer renderer) {
+        return (renderer instanceof PCLRenderer);
+    }
+    
+    /** @see org.apache.fop.render.XMLHandler#getNamespace() */
+    public String getNamespace() {
+        return SVGDOMImplementation.SVG_NAMESPACE_URI;
+    }
+
+}
+

Propchange: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/PCLSVGHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/package.html
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/package.html?rev=397806&r1=397805&r2=397806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/package.html (original)
+++ xmlgraphics/fop/trunk/src/sandbox/org/apache/fop/render/pcl/package.html Fri Apr 28 01:51:27 2006
@@ -1,5 +1,5 @@
 <!--
-  Copyright 2005 The Apache Software Foundation
+  Copyright 2005-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.
@@ -17,6 +17,6 @@
 <HTML>
 <TITLE>org.apache.fop.render.pcl Package</TITLE>
 <BODY>
-<P>PCL Renderer</P>
+<P>PCL Renderer (Supports PCL5 and HP GL/2)</P>
 </BODY>
 </HTML>

Modified: xmlgraphics/fop/trunk/test/java/org/apache/fop/UtilityCodeTestSuite.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/test/java/org/apache/fop/UtilityCodeTestSuite.java?rev=397806&r1=397805&r2=397806&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/test/java/org/apache/fop/UtilityCodeTestSuite.java (original)
+++ xmlgraphics/fop/trunk/test/java/org/apache/fop/UtilityCodeTestSuite.java Fri Apr 28 01:51:27 2006
@@ -21,6 +21,7 @@
 import org.apache.fop.traits.BorderPropsTestCase;
 import org.apache.fop.traits.TraitColorTestCase;
 import org.apache.fop.util.PDFNumberTestCase;
+import org.apache.fop.util.UnitConvTestCase;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
@@ -39,6 +40,7 @@
             "Test suite for FOP's utility classes");
         //$JUnit-BEGIN$
         suite.addTest(new TestSuite(PDFNumberTestCase.class));
+        suite.addTest(new TestSuite(UnitConvTestCase.class));
         suite.addTest(new TestSuite(TraitColorTestCase.class));
         suite.addTest(new TestSuite(BorderPropsTestCase.class));
         //$JUnit-END$

Added: xmlgraphics/fop/trunk/test/java/org/apache/fop/util/UnitConvTestCase.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/fop/trunk/test/java/org/apache/fop/util/UnitConvTestCase.java?rev=397806&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/test/java/org/apache/fop/util/UnitConvTestCase.java (added)
+++ xmlgraphics/fop/trunk/test/java/org/apache/fop/util/UnitConvTestCase.java Fri Apr 28 01:51:27 2006
@@ -0,0 +1,45 @@
+/*
+ * 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.util;
+
+import junit.framework.TestCase;
+
+/**
+ * Test class for UnitConv.
+ */
+public class UnitConvTestCase extends TestCase {
+
+    /**
+     * Test all kinds of unit conversions.
+     * @throws Exception if the test fails
+     */
+    public void testConversions() throws Exception {
+        assertEquals("in2mm", 25.4, UnitConv.in2mm(1), 0.00001);
+        assertEquals("mm2in", 1.0, UnitConv.mm2in(25.4), 0.00001);
+        assertEquals("mm2pt", 841.890, UnitConv.mm2pt(297), 0.001 / 2); //height of an A4 page
+        assertEquals("mm2mpt", 841890, UnitConv.mm2mpt(297), 1.0 / 2);
+        assertEquals("pt2mm", 297, UnitConv.pt2mm(841.890), 0.0001);
+        assertEquals("in2mpt", 792000, UnitConv.in2mpt(11.0), 1.0 / 2); //height of a letter page
+        assertEquals("mpt2in", 11.0, UnitConv.mpt2in(792000), 0.01 / 2); //height of a letter page
+        
+        assertEquals("mm2px/72dpi", 842, UnitConv.mm2px(297, 72), 0.0001);
+        assertEquals("mm2px/300dpi", 3508, UnitConv.mm2px(297, 300), 0.0001);
+    }
+    
+}
\ No newline at end of file

Propchange: xmlgraphics/fop/trunk/test/java/org/apache/fop/util/UnitConvTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native



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