jeremias    2002/08/12 10:05:09

  Modified:    src/org/apache/fop/render/ps Tag: fop-0_20_2-maintain
                        PSRenderer.java
  Added:       src/org/apache/fop/render/ps Tag: fop-0_20_2-maintain
                        RunLengthEncodeOutputStream.java
  Log:
  Added a RunLengthEncode filter for the PostScript renderer.
  Submitted by: Stephen Wolke <[EMAIL PROTECTED]>
  
  Added a property on the PostScript renderer for switching between PostScript
  Level 2 and 3. Default is Level 3. (Jeremias Maerki)
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.15.2.9  +1095 -1062xml-fop/src/org/apache/fop/render/ps/PSRenderer.java
  
  Index: PSRenderer.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/render/ps/PSRenderer.java,v
  retrieving revision 1.15.2.8
  retrieving revision 1.15.2.9
  diff -u -r1.15.2.8 -r1.15.2.9
  --- PSRenderer.java   2 Aug 2002 20:28:57 -0000       1.15.2.8
  +++ PSRenderer.java   12 Aug 2002 17:05:09 -0000      1.15.2.9
  @@ -1,1062 +1,1095 @@
  -/*
  - * $Id$
  - * Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved.
  - * For details on use and redistribution please refer to the
  - * LICENSE file included with these sources.
  - */
  -
  -package org.apache.fop.render.ps;
  -
  -// FOP
  -import org.apache.fop.svg.SVGArea;
  -import org.apache.fop.render.AbstractRenderer;
  -import org.apache.fop.render.Renderer;
  -import org.apache.fop.image.ImageArea;
  -import org.apache.fop.image.FopImage;
  -import org.apache.fop.image.FopImageException;
  -import org.apache.fop.image.JpegImage;
  -import org.apache.fop.layout.*;
  -import org.apache.fop.layout.inline.*;
  -import org.apache.fop.datatypes.*;
  -import org.apache.fop.fo.properties.*;
  -import org.apache.fop.render.pdf.Font;
  -import org.apache.fop.image.*;
  -import org.apache.fop.apps.FOPException;
  -
  -import org.apache.batik.bridge.*;
  -import org.apache.batik.swing.svg.*;
  -import org.apache.batik.swing.gvt.*;
  -import org.apache.batik.gvt.*;
  -import org.apache.batik.gvt.renderer.*;
  -import org.apache.batik.gvt.filter.*;
  -import org.apache.batik.gvt.event.*;
  -
  -// SVG
  -import org.w3c.dom.svg.SVGSVGElement;
  -import org.w3c.dom.svg.SVGDocument;
  -import org.w3c.dom.*;
  -import org.w3c.dom.svg.*;
  -
  -// Java
  -import java.io.*;
  -import java.util.*;
  -import java.io.IOException;
  -import java.io.OutputStream;
  -import java.util.Iterator;
  -import java.util.ArrayList;
  -import java.util.HashMap;
  -import java.awt.geom.AffineTransform;
  -import java.awt.geom.Dimension2D;
  -import java.awt.Point;
  -import java.awt.RenderingHints;
  -import java.awt.Dimension;
  -
  -/*
  -PostScript renderer
  -
  -Remarks:
  -- If anyone modifies this renderer please make sure to also follow the DSC to
  -  make it simpler to programmatically modify the generated Postscript files
  -  (ex. extract pages etc.).
  -- The filters in use are hardcoded at the moment.
  -- Modified by Mark Lillywhite [EMAIL PROTECTED], to use the new
  -  Renderer interface. This PostScript renderer appears to be the
  -  most efficient at producing output.
  -
  -TODO-List:
  -- Character size/spacing
  -- SVG Transcoder for Batik
  -- configuration
  -- move to PrintRenderer
  -- maybe improve filters (I'm not very proud of them)
  -- add a RunLengthEncode filter (useful for Level 2 Postscript)
  -- Improve DocumentProcessColors stuff (probably needs to be configurable, then 
maybe
  -  add a color to grayscale conversion for bitmaps to make output smaller (See
  -  PCLRenderer)
  -- enhanced font support and font embedding
  -- support different character encodings
  -- try to implement image transparency
  -- Add PPD support
  -- fix border painting (see table.fo)
  -
  -*/
  -
  -/**
  - * Renderer that renders to PostScript.
  - * <br>
  - * This class currently generates PostScript Level 2 code. The only exception
  - * is the FlateEncode filter which is a Level 3 feature. The PostScript code
  - * generated follows the Document Structuring Conventions (DSC) version 3.0.
  - *
  - * @author Jeremias Märki
  - */
  -public class PSRenderer extends AbstractRenderer {
  -
  -    /**
  -     * the application producing the PostScript
  -     */
  -    protected String producer;
  -
  -    int imagecount = 0;    // DEBUG
  -    int pagecount = 0;
  -
  -    private boolean enableComments = true;
  -
  -    /**
  -     * the stream used to output the PostScript
  -     */
  -    protected PSStream out;
  -    private boolean ioTrouble = false;
  -
  -    private String currentFontName;
  -    private int currentFontSize;
  -    private int pageHeight;
  -    private int pageWidth;
  -    private float currRed;
  -    private float currGreen;
  -    private float currBlue;
  -
  -    private FontInfo fontInfo;
  -
  -    protected IDReferences idReferences;
  -
  -    protected java.util.HashMap options;
  -
  -
  -    /**
  -     * set the document's producer
  -     *
  -     * @param producer string indicating application producing the PostScript
  -     */
  -    public void setProducer(String producer) {
  -        this.producer = producer;
  -    }
  -
  -
  -    /**
  -     * set up renderer options
  -     */
  -    public void setOptions(java.util.HashMap options) {
  -        this.options = options;
  -    }
  -
  -    /**
  -     * write out a command
  -     */
  -    protected void write(String cmd) {
  -        try {
  -            out.write(cmd);
  -        } catch (IOException e) {
  -            if (!ioTrouble)
  -                e.printStackTrace();
  -            ioTrouble = true;
  -        }
  -    }
  -
  -    /**
  -     * write out a comment
  -     */
  -    protected void comment(String comment) {
  -        if (this.enableComments)
  -            write(comment);
  -    }
  -
  -    protected void writeProcs() {
  -        write("%%BeginResource: procset FOPprocs");
  -        write("%%Title: Utility procedures");
  -        write("/FOPprocs 20 dict dup begin");
  -        write("/bd{bind def}bind def");
  -        write("/ld{load def}bd");
  -        write("/M/moveto ld");
  -        write("/RM/rmoveto ld");
  -        write("/t/show ld");
  -        write("/A/ashow ld");
  -        write("/cp/closepath ld");
  -        write("/re {4 2 roll M"); //define rectangle
  -        write("1 index 0 rlineto");
  -        write("0 exch rlineto");
  -        write("neg 0 rlineto");
  -        write("cp } bd");
  -
  -        write("/ux 0.0 def");
  -        write("/uy 0.0 def");
  -
  -        // <font> <size> F
  -        write("/F {");
  -        write("  /Tp exch def");
  -        // write("  currentdict exch get");
  -        write("  /Tf exch def");
  -        write("  Tf findfont Tp scalefont setfont");
  -        write("  /cf Tf def  /cs Tp def  /cw ( ) stringwidth pop def");
  -        write("} bd");
  -
  -        write("/ULS {currentpoint /uy exch def /ux exch def} bd");
  -        write("/ULE {");
  -        write("  /Tcx currentpoint pop def");
  -        write("  gsave");
  -        write("  newpath");
  -        write("  cf findfont cs scalefont dup");
  -        write("  /FontMatrix get 0 get /Ts exch def /FontInfo get dup");
  -        write("  /UnderlinePosition get Ts mul /To exch def");
  -        write("  /UnderlineThickness get Ts mul /Tt exch def");
  -        write("  ux uy To add moveto  Tcx uy To add lineto");
  -        write("  Tt setlinewidth stroke");
  -        write("  grestore");
  -        write("} bd");
  -
  -        write("/OLE {");
  -        write("  /Tcx currentpoint pop def");
  -        write("  gsave");
  -        write("  newpath");
  -        write("  cf findfont cs scalefont dup");
  -        write("  /FontMatrix get 0 get /Ts exch def /FontInfo get dup");
  -        write("  /UnderlinePosition get Ts mul /To exch def");
  -        write("  /UnderlineThickness get Ts mul /Tt exch def");
  -        write("  ux uy To add cs add moveto Tcx uy To add cs add lineto");
  -        write("  Tt setlinewidth stroke");
  -        write("  grestore");
  -        write("} bd");
  -
  -        write("/SOE {");
  -        write("  /Tcx currentpoint pop def");
  -        write("  gsave");
  -        write("  newpath");
  -        write("  cf findfont cs scalefont dup");
  -        write("  /FontMatrix get 0 get /Ts exch def /FontInfo get dup");
  -        write("  /UnderlinePosition get Ts mul /To exch def");
  -        write("  /UnderlineThickness get Ts mul /Tt exch def");
  -        write("  ux uy To add cs 10 mul 26 idiv add moveto Tcx uy To add cs 10 mul 
26 idiv add lineto");
  -        write("  Tt setlinewidth stroke");
  -        write("  grestore");
  -        write("} bd");
  -        write("end def");
  -        write("%%EndResource");
  -    }
  -
  -    protected void writeFontDict(FontInfo fontInfo) {
  -        write("%%BeginResource: procset FOPFonts");
  -        write("%%Title: Font setup (shortcuts) for this file");
  -        write("/FOPFonts 100 dict dup begin");
  -        // write("/gfF1{/Helvetica findfont} bd");
  -        // write("/gfF3{/Helvetica-Bold findfont} bd");
  -        HashMap fonts = fontInfo.getFonts();
  -        Iterator enum = fonts.keySet().iterator();
  -        while (enum.hasNext()) {
  -            String key = (String)enum.next();
  -            Font fm = (Font)fonts.get(key);
  -            write("/" + key + " /" + fm.fontName() + " def");
  -        }
  -        write("end def");
  -        write("%%EndResource");
  -
  -        //Rewrite font encodings
  -        enum = fonts.keySet().iterator();
  -        while (enum.hasNext()) {
  -            String key = (String)enum.next();
  -            Font fm = (Font)fonts.get(key);
  -            write("/" + fm.fontName() + " findfont");
  -            write("dup length dict begin");
  -            write("  {1 index /FID ne {def} {pop pop} ifelse} forall");
  -            write("  /Encoding ISOLatin1Encoding def");
  -            write("  currentdict");
  -            write("end");
  -            write("/" + fm.fontName() + " exch definefont pop");
  -        }
  -    }
  -
  -    protected void movetoCurrPosition() {
  -        write(this.currentXPosition + " " + this.currentYPosition + " M");
  -    }
  -
  -    /**
  -     * set up the font info
  -     *
  -     * @param fontInfo the font info object to set up
  -     */
  -    public void setupFontInfo(FontInfo fontInfo)
  -        throws FOPException {
  -        /* use PDF's font setup to get PDF metrics */
  -        org.apache.fop.render.pdf.FontSetup.setup(fontInfo);
  -        this.fontInfo = fontInfo;
  -    }
  -
  -    protected void addFilledRect(int x, int y, int w, int h,
  -                                 ColorType col) {
  -        // XXX: cater for braindead, legacy -ve heights
  -        if (h < 0) {
  -           h = -h;
  -        }
  -
  -            write("newpath");
  -            write(x + " " + y + " " + w + " " + -h + " re");
  -            /*
  -            write(x + " " + y + " M");
  -            write(w + " 0 rlineto");
  -            write("0 " + (-h) + " rlineto");
  -            write((-w) + " 0 rlineto");
  -            write("0 " + h + " rlineto");
  -            write("closepath");
  -            */
  -            useColor(col);
  -            write("fill");
  -    }
  -
  -    /**
  -     * render a display space to PostScript
  -     *
  -     * @param space the space to render
  -     */
  -    public void renderDisplaySpace(DisplaySpace space) {
  -        // write("% --- DisplaySpace size="+space.getSize());
  -        this.currentYPosition -= space.getSize();
  -        movetoCurrPosition();
  -    }
  -
  -    /**
  -     * render a foreign object area
  -     */
  -    public void renderForeignObjectArea(ForeignObjectArea area) {
  -        // if necessary need to scale and align the content
  -        this.currentXPosition = this.currentXPosition + area.getXOffset();
  -        int plOffset = 0;
  -        Area parent = area.getParent();
  -        if (parent instanceof LineArea) {
  -            plOffset = ((LineArea)parent).getPlacementOffset();
  -        }
  -        this.currentYPosition += plOffset;
  -        area.getObject().render(this);
  -        this.currentXPosition += area.getEffectiveWidth();
  -        this.currentYPosition -= plOffset;
  -        movetoCurrPosition();
  -    }
  -
  -    /**
  -     * render an SVG area to PostScript
  -     *
  -     * @param area the area to render
  -     */
  -    public void renderSVGArea(SVGArea area) {
  -        int x = this.currentXPosition;
  -        int y = this.currentYPosition;
  -        renderSVGDocument(area.getSVGDocument(), x, y, area.getFontState());
  -    }
  -
  -
  -    /**
  -     * render SVG document to PostScript
  -     *
  -     * @param doc  the document to render
  -     * @param x    the x offset
  -     * @param y    the y offset
  -     * @param fs   the fontstate to use
  -     */
  -    protected void renderSVGDocument(Document doc, int x, int y,
  -            FontState fs) {
  -        org.apache.fop.svg.SVGUserAgent userAgent
  -            = new org.apache.fop.svg.SVGUserAgent(new AffineTransform());
  -        userAgent.setLogger(log);
  -
  -        GVTBuilder builder = new GVTBuilder();
  -        BridgeContext ctx = new BridgeContext(userAgent);
  -
  -        GraphicsNode root;
  -        try {
  -            root = builder.build(ctx, doc);
  -        } catch (Exception e) {
  -            log.error("svg graphic could not be built: "
  -                                   + e.getMessage(), e);
  -            return;
  -        }
  -        // get the 'width' and 'height' attributes of the SVG document
  -        float w = (float)ctx.getDocumentSize().getWidth() * 1000f;
  -        float h = (float)ctx.getDocumentSize().getHeight() * 1000f;
  -
  -        //log.debug("drawing SVG image: "+x+"/"+y+" "+w+"/"+h);
  -
  -        ctx = null;
  -        builder = null;
  -
  -        float sx = 1, sy = -1;
  -        int xOffset = x, yOffset = y;
  -
  -        comment("% --- SVG Area");
  -        write("gsave");
  -        if (w != 0 && h != 0) {
  -            write("newpath");
  -            write(x + " " + y + " M");
  -            write((x + w) + " " + y + " rlineto");
  -            write((x + w) + " " + (y - h) + " rlineto");
  -            write(x + " " + (y - h) + " rlineto");
  -            write("closepath");
  -            write("clippath");
  -        }
  -        // transform so that the coordinates (0,0) is from the top left
  -        // and positive is down and to the right. (0,0) is where the
  -        // viewBox puts it.
  -        write(xOffset + " " + yOffset + " translate");
  -        write(sx + " " + sy + " scale");
  -
  -        PSGraphics2D graphics = new PSGraphics2D(false, fs,
  -                                this, currentFontName,
  -                                currentFontSize,
  -                                currentXPosition,
  -                                currentYPosition);
  -        graphics.setGraphicContext(new 
org.apache.batik.ext.awt.g2d.GraphicContext());
  -        try {
  -            root.paint(graphics);
  -        } catch (Exception e) {
  -            log.error("svg graphic could not be rendered: "
  -                                   + e.getMessage(), e);
  -        }
  -
  -        write("grestore");
  -
  -        comment("% --- SVG Area end");
  -    }
  -
  -    /**
  -     * Renders an image, scaling it to the given width and height.
  -     * If the scaled width and height is the same intrinsic size
  -     * of the image, the image is not scaled.
  -     *
  -     * @param x the x position of left edge in millipoints
  -     * @param y the y position of top edge in millipoints
  -     * @param w the width in millipoints
  -     * @param h the height in millipoints
  -     * @param image the image to be rendered
  -     * @param fs the font state to use when rendering text
  -     *           in non-bitmapped images.
  -     */
  -    protected void drawImageScaled(int x, int y, int w, int h,
  -                   FopImage image,
  -                   FontState fs) {
  -        //log.debug("drawing scaled image: "+x+"/"+y+" "+w+"/"+h);
  -        if (image instanceof SVGImage) {
  -            try {
  -                renderSVGDocument(((SVGImage)image).getSVGDocument(), x, y, fs);
  -            } catch (FopImageException e) {
  -                log.error("Error rendering SVG image", e);
  -            }
  -        } else if (image instanceof EPSImage) {
  -            renderEPS(image, x, y, w, h);
  -        } else {
  -            renderBitmap(image, x, y, w, h);
  -        }
  -    }
  -
  -    /**
  -     * Renders an image, clipping it as specified.
  -     *
  -     * @param x the x position of left edge in millipoints.
  -     * @param y the y position of top edge in millipoints.
  -     * @param clipX the left edge of the clip in millipoints
  -     * @param clipY the top edge of the clip in millipoints
  -     * @param clipW the clip width in millipoints
  -     * @param clipH the clip height in millipoints
  -     * @param image the image to be rendered
  -     * @param fs the font state to use when rendering text
  -     *           in non-bitmapped images.
  -     */
  -    protected void drawImageClipped(int x, int y,
  -                    int clipX, int clipY,
  -                    int clipW, int clipH,
  -                    FopImage image,
  -                    FontState fs) {
  -        //log.debug("drawing clipped image: "+x+"/"+y+" "+clipX+"/"+clipY+" 
"+clipW+"/"+clipH);
  -        write("gsave");
  -        write(clipX + " " + clipY + " " + clipW + " " + clipH + " re");
  -        write("clippath");
  -
  -        try {
  -            int w = image.getWidth() * 1000;
  -            int h = image.getHeight() * 1000;
  -
  -            drawImageScaled(x, y, w, h, image, fs);
  -        } catch (FopImageException e) {
  -            log.error("Error getting image extents", e);
  -        }
  -        write("grestore");
  -    }
  -
  -    public void renderEPS(FopImage img, int x, int y, int w, int h) {
  -        try {
  -            EPSImage eimg = (EPSImage)img;
  -            int[] bbox = eimg.getBBox();
  -            int bboxw = bbox[2] - bbox[0];
  -            int bboxh = bbox[3] - bbox[1];
  -
  -
  -            write("%%BeginDocument: " + eimg.getDocName());
  -            write("BeginEPSF");
  -
  -            write(x + " " + (y - h) + " translate");
  -            write("0.0 rotate");
  -            write((long)(w/bboxw) + " " + (long)(h/bboxh) + " scale");
  -            write(-bbox[0] + " " + (-bbox[1]) + " translate");
  -            write(bbox[0] + " " + bbox[1] + " " + bboxw + " " + bboxh + " 
rectclip");
  -            write("newpath");
  -            out.writeByteArr(img.getBitmaps());
  -            write("%%EndDocument");
  -            write("EndEPSF");
  -            write("");
  -        } catch (Exception e) {
  -            e.printStackTrace();
  -            log.error("PSRenderer.renderImageArea(): Error rendering bitmap ("
  -                                   + e.getMessage() + ")", e);
  -        }
  -    }
  -
  -    public void renderBitmap(FopImage img, int x, int y, int w, int h) {
  -        try {
  -            boolean iscolor = img.getColorSpace().getColorSpace()
  -                              != ColorSpace.DEVICE_GRAY;
  -            byte[] imgmap = img.getBitmaps();
  -
  -            write("gsave");
  -            if (img.getColorSpace().getColorSpace() == ColorSpace.DEVICE_CMYK)
  -                write("/DeviceCMYK setcolorspace");
  -            else
  -                write("/DeviceRGB setcolorspace");
  -
  -            write(x + " " + (y - h) + " translate");
  -            write(w + " " + h + " scale");
  -            write("<<");
  -            write("  /ImageType 1");
  -            write("  /Width " + img.getWidth());
  -            write("  /Height " + img.getHeight());
  -            write("  /BitsPerComponent 8");
  -            if (img.getColorSpace().getColorSpace() == ColorSpace.DEVICE_CMYK) {
  -                if (img.invertImage())
  -                    write("  /Decode [1 0 1 0 1 0 1 0]");
  -                else
  -                    write("  /Decode [0 1 0 1 0 1 0 1]");
  -            } else if (iscolor) {
  -                write("  /Decode [0 1 0 1 0 1]");
  -            } else {
  -                write("  /Decode [0 1]");
  -            }
  -            // Setup scanning for left-to-right and top-to-bottom
  -            write("  /ImageMatrix [" + img.getWidth() + " 0 0 -"
  -                  + img.getHeight() + " 0 " + img.getHeight() + "]");
  -
  -            if (img instanceof JpegImage)
  -                write("  /DataSource currentfile /ASCII85Decode filter /DCTDecode 
filter");
  -            else
  -                write("  /DataSource currentfile /ASCII85Decode filter /FlateDecode 
filter");
  -            // write("  /DataSource currentfile /ASCIIHexDecode filter /FlateDecode 
filter");
  -            // write("  /DataSource currentfile /ASCII85Decode filter 
/RunLengthDecode filter");
  -            // write("  /DataSource currentfile /ASCIIHexDecode filter 
/RunLengthDecode filter");
  -            // write("  /DataSource currentfile /ASCIIHexDecode filter");
  -            // write("  /DataSource currentfile /ASCII85Decode filter");
  -            // write("  /DataSource currentfile /RunLengthDecode filter");
  -            write(">>");
  -            write("image");
  -
  -            /*
  -             * for (int y=0; y<img.getHeight(); y++) {
  -             * int indx = y * img.getWidth();
  -             * if (iscolor) indx*= 3;
  -             * for (int x=0; x<img.getWidth(); x++) {
  -             * if (iscolor) {
  -             * writeASCIIHex(imgmap[indx++] & 0xFF);
  -             * writeASCIIHex(imgmap[indx++] & 0xFF);
  -             * writeASCIIHex(imgmap[indx++] & 0xFF);
  -             * } else {
  -             * writeASCIIHex(imgmap[indx++] & 0xFF);
  -             * }
  -             * }
  -             * }
  -             */
  -            try {
  -                // imgmap[0] = 1;
  -                OutputStream out = this.out;
  -                out = new ASCII85OutputStream(out);
  -                if (!(img instanceof JpegImage)) {
  -                    out = new FlateEncodeOutputStream(out);
  -                }
  -                out.write(imgmap);
  -                ((Finalizable)out).finalizeStream();
  -            } catch (IOException e) {
  -                if (!ioTrouble)
  -                    e.printStackTrace();
  -                ioTrouble = true;
  -            }
  -
  -            write("");
  -            write("grestore");
  -        } catch (FopImageException e) {
  -            log.error("PSRenderer.renderImageArea(): Error rendering bitmap ("
  -                                   + e.getMessage() + ")", e);
  -        }
  -    }
  -
  -    /**
  -     * Render an image area.
  -     *
  -     * @param area the image area to render
  -     */
  -    public void renderImageArea(ImageArea area) {
  -        // adapted from contribution by BoBoGi
  -        int x = this.currentXPosition + area.getXOffset();
  -        int ploffset = 0;
  -        if (area.getParent() instanceof LineArea) {
  -            ploffset = ((LineArea)area.getParent()).getPlacementOffset();
  -        }
  -        int y = this.currentYPosition + ploffset;
  -        int w = area.getContentWidth();
  -        int h = area.getHeight();
  -
  -        //this.currentYPosition -= h;
  -        this.currentXPosition += w;
  -
  -        FopImage img = area.getImage();
  -
  -        if (img == null) {
  -            log.error("Error while loading image: area.getImage() is null");
  -        } else {
  -            drawImageScaled(x, y, w, h, img, area.getFontState());
  -        }
  -        movetoCurrPosition();
  -    }
  -
  -
  -    /**
  -     * render an image area to PostScript
  -     *
  -     * @param area the area to render
  -     */
  -     /*
  -    public void renderImageArea(ImageArea area) {
  -        int x = this.currentXPosition + area.getXOffset();
  -        int ploffset = 0;
  -        if (area.getParent() instanceof LineArea) {
  -            ploffset = ((LineArea)area.getParent()).getPlacementOffset();
  -        }
  -        int y = this.currentYPosition + ploffset;
  -        int w = area.getContentWidth();
  -        int h = area.getHeight();
  -        this.currentYPosition -= area.getHeight();
  -
  -        imagecount++;
  -        // if (imagecount!=4) return;
  -
  -        comment("% --- ImageArea");
  -        if (area.getImage() instanceof SVGImage) {
  -            renderSVGDocument(((SVGImage)area.getImage()).getSVGDocument(), x, y, 
area.getFontState());
  -        } else if (area.getImage() instanceof EPSImage) {
  -            renderEPS(area.getImage(), x, y, w, h);
  -        } else {
  -            renderBitmap(area.getImage(), x, y, w, h);
  -        }
  -        comment("% --- ImageArea end");
  -    }*/
  -
  -    /**
  -     * render an inline area to PostScript
  -     *
  -     * @param area the area to render
  -     */
  -    public void renderWordArea(WordArea area) {
  -        movetoCurrPosition();
  -        FontState fs = area.getFontState();
  -        String fontWeight = fs.getFontWeight();
  -        StringBuffer sb = new StringBuffer();
  -        String s;
  -        if (area.getPageNumberID()
  -                != null) {    // this text is a page number, so resolve it
  -            s = idReferences.getPageNumber(area.getPageNumberID());
  -            if (s == null) {
  -                s = "";
  -            }
  -        } else {
  -            s = area.getText();
  -        }
  -        int l = s.length();
  -
  -        for (int i = 0; i < l; i++) {
  -            char ch = s.charAt(i);
  -            char mch = fs.mapChar(ch);
  -            if (mch > 127) {
  -                sb = sb.append("\\" + Integer.toOctalString(mch));
  -            } else {
  -                String escape = "\\()[]{}";
  -                if (escape.indexOf(mch) >= 0) {
  -                    sb.append("\\");
  -                }
  -                sb = sb.append(mch);
  -            }
  -        }
  -
  -        String psString = null;
  -        if (area.getFontState().getLetterSpacing() > 0) {
  -            //float f = area.getFontState().getLetterSpacing() * 1000 / 
this.currentFontSize;
  -            float f = area.getFontState().getLetterSpacing();
  -            psString = (new StringBuffer().append(f).append(" 0.0 (").append(sb).
  -                        append(") A")).toString();
  -        } else {
  -            psString = (new StringBuffer("(").append(sb).append(") t")).toString();
  -        }
  -
  -
  -        // System.out.println("["+s+"] --> ["+sb.toString()+"]");
  -
  -        // comment("% --- InlineArea font-weight="+fontWeight+": " + 
sb.toString());
  -        useFont(fs.getFontName(), fs.getFontSize());
  -        useColor(area.getRed(), area.getGreen(), area.getBlue());
  -        if (area.getUnderlined() || area.getLineThrough()
  -                || area.getOverlined())
  -            write("ULS");
  -        write(psString);
  -        if (area.getUnderlined())
  -            write("ULE");
  -        if (area.getLineThrough())
  -            write("SOE");
  -        if (area.getOverlined())
  -            write("OLE");
  -        this.currentXPosition += area.getContentWidth();
  -    }
  -
  -    public void useFont(String name, int size) {
  -        if ((currentFontName != name) || (currentFontSize != size)) {
  -            write(name + " " + size + " F");
  -            currentFontName = name;
  -            currentFontSize = size;
  -        }
  -    }
  -
  -    /**
  -     * render an inline space to PostScript
  -     *
  -     * @param space the space to render
  -     */
  -    public void renderInlineSpace(InlineSpace space) {
  -        // write("% --- InlineSpace size="+space.getSize());
  -        if (space.getUnderlined() || space.getLineThrough()
  -                || space.getOverlined()) {
  -            //start textdeko
  -            movetoCurrPosition();
  -            write("ULS");
  -
  -            write(space.getSize() + " 0 RM");
  -
  -            //end textdeko
  -            if (space.getUnderlined())
  -                write("ULE");
  -            if (space.getLineThrough())
  -                write("SOE");
  -            if (space.getOverlined())
  -                write("OLE");
  -        }
  -        this.currentXPosition += space.getSize();
  -    }
  -
  -    /**
  -     * render a line area to PostScript
  -     *
  -     * @param area the area to render
  -     */
  -    public void renderLineArea(LineArea area) {
  -        int rx = this.currentAreaContainerXPosition + area.getStartIndent();
  -        int ry = this.currentYPosition;
  -        int w = area.getContentWidth();
  -        int h = area.getHeight();
  -
  -        this.currentYPosition -= area.getPlacementOffset();
  -        this.currentXPosition = rx;
  -
  -        int bl = this.currentYPosition;
  -        // method is identical to super method except next line
  -        movetoCurrPosition();
  -
  -        String fontWeight = area.getFontState().getFontWeight();
  -        //comment("% --- LineArea begin font-weight="+fontWeight);
  -        ArrayList children = area.getChildren();
  -        for (int i = 0; i < children.size(); i++) {
  -            Box b = (Box)children.get(i);
  -            this.currentYPosition = ry - area.getPlacementOffset();
  -            b.render(this);
  -        }
  -        //comment("% --- LineArea end");
  -
  -        this.currentYPosition = ry - h;
  -        this.currentXPosition = rx;
  -    }
  -
  -    /**
  -     * render a page to PostScript
  -     *
  -     * @param page the page to render
  -     */
  -    public void renderPage(Page page) {
  -        this.pagecount++;
  -        this.idReferences = page.getIDReferences();
  -
  -        write("%%Page: " + page.getNumber() + " " + page.getNumber());
  -        write("%%PageBoundingBox: 0 0 " +
  -                Math.round(page.getWidth() / 1000f) + " " +
  -                Math.round(page.getHeight() / 1000f));
  -        write("%%BeginPageSetup");
  -        write("FOPprocs begin");
  -        write("FOPFonts begin");
  -        write("0.001 0.001 scale");
  -        write("%%EndPageSetup");
  -        renderRegions(page);
  -        write("showpage");
  -        write("%%PageTrailer");
  -        write("%%EndPage"); //This is non-standard, but used by Adobe.
  -    }
  -
  -    /**
  -     * render a leader area to PostScript
  -     *
  -     * @param area the area to render
  -     */
  -    public void renderLeaderArea(LeaderArea area) {
  -        int rx = this.currentXPosition;
  -        int ry = this.currentYPosition;
  -        int w = area.getContentWidth();
  -        int th = area.getRuleThickness();
  -        int th2 = th / 2;
  -        int th3 = th / 3;
  -        int th4 = th / 4;
  -
  -        switch (area.getLeaderPattern()) {
  -        case LeaderPattern.SPACE:
  -            // NOP
  -
  -            break;
  -        case LeaderPattern.RULE:
  -            if (area.getRuleStyle() == RuleStyle.NONE)
  -                break;
  -            useColor(area.getRed(), area.getGreen(), area.getBlue());
  -            write("gsave");
  -            write("0 setlinecap");
  -            switch (area.getRuleStyle()) {
  -            case RuleStyle.DOTTED:
  -                write("newpath");
  -                write("[1000 3000] 0 setdash");
  -                write(th + " setlinewidth");
  -                write(rx + " " + ry + " M");
  -                write(w + " 0 rlineto");
  -                useColor(area.getRed(), area.getGreen(), area.getBlue());
  -                write("stroke");
  -                break;
  -            case RuleStyle.DASHED:
  -                write("newpath");
  -                write("[3000 3000] 0 setdash");
  -                write(th + " setlinewidth");
  -                write(rx + " " + ry + " M");
  -                write(w + " 0 rlineto");
  -                useColor(area.getRed(), area.getGreen(), area.getBlue());
  -                write("stroke");
  -                break;
  -            case RuleStyle.SOLID:
  -                write("newpath");
  -                write(th + " setlinewidth");
  -                write(rx + " " + ry + " M");
  -                write(w + " 0 rlineto");
  -                useColor(area.getRed(), area.getGreen(), area.getBlue());
  -                write("stroke");
  -                break;
  -            case RuleStyle.DOUBLE:
  -                write("newpath");
  -                write(th3 + " setlinewidth");
  -                write(rx + " " + (ry - th3) + " M");
  -                write(w + " 0 rlineto");
  -                write(rx + " " + (ry + th3) + " M");
  -                write(w + " 0 rlineto");
  -                useColor(area.getRed(), area.getGreen(), area.getBlue());
  -                write("stroke");
  -                break;
  -            case RuleStyle.GROOVE:
  -                write(th2 + " setlinewidth");
  -                write("newpath");
  -                write(rx + " " + (ry - th4) + " M");
  -                write(w + " 0 rlineto");
  -                useColor(area.getRed(), area.getGreen(), area.getBlue());
  -                write("stroke");
  -                write("newpath");
  -                write(rx + " " + (ry + th4) + " M");
  -                write(w + " 0 rlineto");
  -                useColor(1, 1, 1);    // white
  -                write("stroke");
  -                break;
  -            case RuleStyle.RIDGE:
  -                write(th2 + " setlinewidth");
  -                write("newpath");
  -                write(rx + " " + (ry - th4) + " M");
  -                write(w + " 0 rlineto");
  -                useColor(1, 1, 1);    // white
  -                write("stroke");
  -                write("newpath");
  -                write(rx + " " + (ry + th4) + " M");
  -                write(w + " 0 rlineto");
  -                useColor(area.getRed(), area.getGreen(), area.getBlue());
  -                write("stroke");
  -                break;
  -            }
  -            write("grestore");
  -            break;
  -        case LeaderPattern.DOTS:
  -            comment("% --- Leader dots NYI");
  -            log.error("Leader dots: Not yet implemented");
  -            break;
  -        case LeaderPattern.USECONTENT:
  -            comment("% --- Leader use-content NYI");
  -            log.error("Leader use-content: Not yet implemented");
  -            break;
  -        }
  -        this.currentXPosition += area.getContentWidth();
  -        write(area.getContentWidth() + " 0 RM");
  -    }
  -
  -    protected void doFrame(Area area) {
  -        int w, h;
  -        int rx = this.currentAreaContainerXPosition;
  -        w = area.getContentWidth();
  -        BorderAndPadding bap = area.getBorderAndPadding();
  -
  -        if (area instanceof BlockArea)
  -            rx += ((BlockArea)area).getStartIndent();
  -
  -        h = area.getContentHeight();
  -        int ry = this.currentYPosition;
  -
  -        rx = rx - area.getPaddingLeft();
  -        ry = ry + area.getPaddingTop();
  -        w = w + area.getPaddingLeft() + area.getPaddingRight();
  -        h = h + area.getPaddingTop() + area.getPaddingBottom();
  -
  -        rx = rx - area.getBorderLeftWidth();
  -        ry = ry + area.getBorderTopWidth();
  -        w = w + area.getBorderLeftWidth() + area.getBorderRightWidth();
  -        h = h + area.getBorderTopWidth() + area.getBorderBottomWidth();
  -
  -        doBackground(area, rx, ry, w, h);
  -
  -        if (area.getBorderTopWidth() != 0) {
  -            write("newpath");
  -            write(rx + " " + ry + " M");
  -            write(w + " 0 rlineto");
  -            write(area.getBorderTopWidth() + " setlinewidth");
  -            write("0 setlinecap");
  -            useColor(bap.getBorderColor(BorderAndPadding.TOP));
  -            write("stroke");
  -        }
  -        if (area.getBorderLeftWidth() != 0) {
  -            write("newpath");
  -            write(rx + " " + ry + " M");
  -            write("0 " + (-h) + " rlineto");
  -            write(area.getBorderLeftWidth() + " setlinewidth");
  -            write("0 setlinecap");
  -            useColor(bap.getBorderColor(BorderAndPadding.LEFT));
  -            write("stroke");
  -        }
  -        if (area.getBorderRightWidth() != 0) {
  -            write("newpath");
  -            write((rx + w) + " " + ry + " M");
  -            write("0 " + (-h) + " rlineto");
  -            write(area.getBorderRightWidth() + " setlinewidth");
  -            write("0 setlinecap");
  -            useColor(bap.getBorderColor(BorderAndPadding.RIGHT));
  -            write("stroke");
  -        }
  -        if (area.getBorderBottomWidth() != 0) {
  -            write("newpath");
  -            write(rx + " " + (ry - h) + " M");
  -            write(w + " 0 rlineto");
  -            write(area.getBorderBottomWidth() + " setlinewidth");
  -            write("0 setlinecap");
  -            useColor(bap.getBorderColor(BorderAndPadding.BOTTOM));
  -            write("stroke");
  -        }
  -    }
  -
  -    private void useColor(ColorType col) {
  -        useColor(col.red(), col.green(), col.blue());
  -    }
  -
  -    private void useColor(float red, float green, float blue) {
  -        if ((red != currRed) || (green != currGreen) || (blue != currBlue)) {
  -            write(red + " " + green + " " + blue + " setrgbcolor");
  -            currRed = red;
  -            currGreen = green;
  -            currBlue = blue;
  -        }
  -    }
  -
  -    /**
  -      Default start renderer method. This would
  -      normally be overridden. ([EMAIL PROTECTED]).
  -    */
  -    public void startRenderer(OutputStream outputStream)
  -    throws IOException {
  -        log.debug("rendering areas to PostScript");
  -
  -        this.pagecount = 0;
  -        this.out = new PSStream(outputStream);
  -        write("%!PS-Adobe-3.0");
  -        if (this.producer == null) {
  -            this.producer = org.apache.fop.apps.Version.getVersion();
  -        }
  -        write("%%Creator: "+this.producer);
  -        write("%%Pages: (atend)");
  -        write("%%DocumentProcessColors: Black");
  -        write("%%DocumentSuppliedResources: procset FOPFonts");
  -        write("%%EndComments");
  -        write("%%BeginDefaults");
  -        write("%%EndDefaults");
  -        write("%%BeginProlog");
  -        write("%%EndProlog");
  -        write("%%BeginSetup");
  -        writeProcs();
  -        writeFontDict(fontInfo);
  -
  -        /* Write proc for including EPS */
  -        write("%%BeginResource: procset EPSprocs");
  -        write("%%Title: EPS encapsulation procs");
  -
  -        write("/BeginEPSF { %def");
  -        write("/b4_Inc_state save def         % Save state for cleanup");
  -        write("/dict_count countdictstack def % Count objects on dict stack");
  -        write("/op_count count 1 sub def      % Count objects on operand stack");
  -        write("userdict begin                 % Push userdict on dict stack");
  -        write("/showpage { } def              % Redefine showpage, { } = null 
proc");
  -        write("0 setgray 0 setlinecap         % Prepare graphics state");
  -        write("1 setlinewidth 0 setlinejoin");
  -        write("10 setmiterlimit [ ] 0 setdash newpath");
  -        write("/languagelevel where           % If level not equal to 1 then");
  -        write("{pop languagelevel             % set strokeadjust and");
  -        write("1 ne                           % overprint to their defaults.");
  -        write("{false setstrokeadjust false setoverprint");
  -        write("} if");
  -        write("} if");
  -        write("} bind def");
  -
  -        write("/EndEPSF { %def");
  -        write("count op_count sub {pop} repeat            % Clean up stacks");
  -        write("countdictstack dict_count sub {end} repeat");
  -        write("b4_Inc_state restore");
  -        write("} bind def");
  -        write("%%EndResource");
  -
  -        write("%%EndSetup");
  -    }
  -
  -    /**
  -      Default stop renderer method. This would
  -      normally be overridden. ([EMAIL PROTECTED]).
  -    */
  -    public void stopRenderer(OutputStream outputStream)
  -    throws IOException {
  -        write("%%Trailer");
  -        write("%%Pages: "+this.pagecount);
  -        write("%%EOF");
  -        this.out.flush();
  -        log.debug("written out PostScript");
  -    }
  -
  -    public void render(Page page, OutputStream outputStream) {
  -        this.renderPage(page);
  -    }
  -}
  +/*
  + * $Id$
  + * Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved.
  + * For details on use and redistribution please refer to the
  + * LICENSE file included with these sources.
  + */
  +
  +package org.apache.fop.render.ps;
  +
  +// FOP
  +import org.apache.fop.svg.SVGArea;
  +import org.apache.fop.render.AbstractRenderer;
  +import org.apache.fop.render.Renderer;
  +import org.apache.fop.image.ImageArea;
  +import org.apache.fop.image.FopImage;
  +import org.apache.fop.image.FopImageException;
  +import org.apache.fop.image.JpegImage;
  +import org.apache.fop.layout.*;
  +import org.apache.fop.layout.inline.*;
  +import org.apache.fop.datatypes.*;
  +import org.apache.fop.fo.properties.*;
  +import org.apache.fop.render.pdf.Font;
  +import org.apache.fop.image.*;
  +import org.apache.fop.apps.FOPException;
  +
  +import org.apache.batik.bridge.*;
  +import org.apache.batik.swing.svg.*;
  +import org.apache.batik.swing.gvt.*;
  +import org.apache.batik.gvt.*;
  +import org.apache.batik.gvt.renderer.*;
  +import org.apache.batik.gvt.filter.*;
  +import org.apache.batik.gvt.event.*;
  +
  +// SVG
  +import org.w3c.dom.svg.SVGSVGElement;
  +import org.w3c.dom.svg.SVGDocument;
  +import org.w3c.dom.*;
  +import org.w3c.dom.svg.*;
  +
  +// Java
  +import java.io.*;
  +import java.util.*;
  +import java.io.IOException;
  +import java.io.OutputStream;
  +import java.util.Iterator;
  +import java.util.ArrayList;
  +import java.util.HashMap;
  +import java.awt.geom.AffineTransform;
  +import java.awt.geom.Dimension2D;
  +import java.awt.Point;
  +import java.awt.RenderingHints;
  +import java.awt.Dimension;
  +
  +/*
  +PostScript renderer
  +
  +Remarks:
  +- If anyone modifies this renderer please make sure to also follow the DSC to
  +  make it simpler to programmatically modify the generated Postscript files
  +  (ex. extract pages etc.).
  +- The filters in use are hardcoded at the moment.
  +- Modified by Mark Lillywhite [EMAIL PROTECTED], to use the new
  +  Renderer interface. This PostScript renderer appears to be the
  +  most efficient at producing output.
  +
  +TODO-List:
  +- Character size/spacing
  +- SVG Transcoder for Batik
  +- configuration
  +- move to PrintRenderer
  +- maybe improve filters (I'm not very proud of them)
  +- add a RunLengthEncode filter (useful for Level 2 Postscript)
  +- Improve DocumentProcessColors stuff (probably needs to be configurable, then maybe
  +  add a color to grayscale conversion for bitmaps to make output smaller (See
  +  PCLRenderer)
  +- enhanced font support and font embedding
  +- support different character encodings
  +- try to implement image transparency
  +- Add PPD support
  +- fix border painting (see table.fo)
  +
  +*/
  +
  +/**
  + * Renderer that renders to PostScript.
  + * <br>
  + * This class currently generates PostScript Level 2 code. The only exception
  + * is the FlateEncode filter which is a Level 3 feature. The PostScript code
  + * generated follows the Document Structuring Conventions (DSC) version 3.0.
  + *
  + * @author Jeremias Märki
  + */
  +public class PSRenderer extends AbstractRenderer {
  +
  +    /**
  +     * the application producing the PostScript
  +     */
  +    protected String producer;
  +
  +    int imagecount = 0;    // DEBUG
  +    int pagecount = 0;
  +
  +    private boolean enableComments = true;
  +
  +    /**
  +     * the stream used to output the PostScript
  +     */
  +    protected PSStream out;
  +    private boolean ioTrouble = false;
  +
  +    private String currentFontName;
  +    private int currentFontSize;
  +    private int pageHeight;
  +    private int pageWidth;
  +    private float currRed;
  +    private float currGreen;
  +    private float currBlue;
  +
  +    private FontInfo fontInfo;
  +
  +    private int psLevel = 3;
  +
  +    protected IDReferences idReferences;
  +
  +    protected java.util.HashMap options;
  +
  +
  +    /**
  +     * set the document's producer
  +     *
  +     * @param producer string indicating application producing the PostScript
  +     */
  +    public void setProducer(String producer) {
  +        this.producer = producer;
  +    }
  +
  +
  +    /**
  +     * set up renderer options
  +     */
  +    public void setOptions(java.util.HashMap options) {
  +        this.options = options;
  +    }
  +
  +
  +    /**
  +     * Sets the PostScript Level to generate.
  +     *
  +     * @param level You can specify either 2 or 3 for the PostScript Level
  +     */
  +    public void setPSLevel(int level) {
  +        switch (level) {
  +            case 2:
  +            case 3:
  +                this.psLevel = level;
  +                break;
  +            default:
  +                throw new IllegalArgumentException("Only PostScript Levels 2 and 3 
are supported");
  +        }
  +    }
  +
  +
  +    public int getPSLevel() {
  +        return this.psLevel;
  +    }
  +
  +
  +    /**
  +     * write out a command
  +     */
  +    protected void write(String cmd) {
  +        try {
  +            out.write(cmd);
  +        } catch (IOException e) {
  +            if (!ioTrouble)
  +                e.printStackTrace();
  +            ioTrouble = true;
  +        }
  +    }
  +
  +    /**
  +     * write out a comment
  +     */
  +    protected void comment(String comment) {
  +        if (this.enableComments)
  +            write(comment);
  +    }
  +
  +    protected void writeProcs() {
  +        write("%%BeginResource: procset FOPprocs");
  +        write("%%Title: Utility procedures");
  +        write("/FOPprocs 20 dict dup begin");
  +        write("/bd{bind def}bind def");
  +        write("/ld{load def}bd");
  +        write("/M/moveto ld");
  +        write("/RM/rmoveto ld");
  +        write("/t/show ld");
  +        write("/A/ashow ld");
  +        write("/cp/closepath ld");
  +        write("/re {4 2 roll M"); //define rectangle
  +        write("1 index 0 rlineto");
  +        write("0 exch rlineto");
  +        write("neg 0 rlineto");
  +        write("cp } bd");
  +
  +        write("/ux 0.0 def");
  +        write("/uy 0.0 def");
  +
  +        // <font> <size> F
  +        write("/F {");
  +        write("  /Tp exch def");
  +        // write("  currentdict exch get");
  +        write("  /Tf exch def");
  +        write("  Tf findfont Tp scalefont setfont");
  +        write("  /cf Tf def  /cs Tp def  /cw ( ) stringwidth pop def");
  +        write("} bd");
  +
  +        write("/ULS {currentpoint /uy exch def /ux exch def} bd");
  +        write("/ULE {");
  +        write("  /Tcx currentpoint pop def");
  +        write("  gsave");
  +        write("  newpath");
  +        write("  cf findfont cs scalefont dup");
  +        write("  /FontMatrix get 0 get /Ts exch def /FontInfo get dup");
  +        write("  /UnderlinePosition get Ts mul /To exch def");
  +        write("  /UnderlineThickness get Ts mul /Tt exch def");
  +        write("  ux uy To add moveto  Tcx uy To add lineto");
  +        write("  Tt setlinewidth stroke");
  +        write("  grestore");
  +        write("} bd");
  +
  +        write("/OLE {");
  +        write("  /Tcx currentpoint pop def");
  +        write("  gsave");
  +        write("  newpath");
  +        write("  cf findfont cs scalefont dup");
  +        write("  /FontMatrix get 0 get /Ts exch def /FontInfo get dup");
  +        write("  /UnderlinePosition get Ts mul /To exch def");
  +        write("  /UnderlineThickness get Ts mul /Tt exch def");
  +        write("  ux uy To add cs add moveto Tcx uy To add cs add lineto");
  +        write("  Tt setlinewidth stroke");
  +        write("  grestore");
  +        write("} bd");
  +
  +        write("/SOE {");
  +        write("  /Tcx currentpoint pop def");
  +        write("  gsave");
  +        write("  newpath");
  +        write("  cf findfont cs scalefont dup");
  +        write("  /FontMatrix get 0 get /Ts exch def /FontInfo get dup");
  +        write("  /UnderlinePosition get Ts mul /To exch def");
  +        write("  /UnderlineThickness get Ts mul /Tt exch def");
  +        write("  ux uy To add cs 10 mul 26 idiv add moveto Tcx uy To add cs 10 mul 
26 idiv add lineto");
  +        write("  Tt setlinewidth stroke");
  +        write("  grestore");
  +        write("} bd");
  +        write("end def");
  +        write("%%EndResource");
  +    }
  +
  +    protected void writeFontDict(FontInfo fontInfo) {
  +        write("%%BeginResource: procset FOPFonts");
  +        write("%%Title: Font setup (shortcuts) for this file");
  +        write("/FOPFonts 100 dict dup begin");
  +        // write("/gfF1{/Helvetica findfont} bd");
  +        // write("/gfF3{/Helvetica-Bold findfont} bd");
  +        HashMap fonts = fontInfo.getFonts();
  +        Iterator enum = fonts.keySet().iterator();
  +        while (enum.hasNext()) {
  +            String key = (String)enum.next();
  +            Font fm = (Font)fonts.get(key);
  +            write("/" + key + " /" + fm.fontName() + " def");
  +        }
  +        write("end def");
  +        write("%%EndResource");
  +
  +        //Rewrite font encodings
  +        enum = fonts.keySet().iterator();
  +        while (enum.hasNext()) {
  +            String key = (String)enum.next();
  +            Font fm = (Font)fonts.get(key);
  +            write("/" + fm.fontName() + " findfont");
  +            write("dup length dict begin");
  +            write("  {1 index /FID ne {def} {pop pop} ifelse} forall");
  +            write("  /Encoding ISOLatin1Encoding def");
  +            write("  currentdict");
  +            write("end");
  +            write("/" + fm.fontName() + " exch definefont pop");
  +        }
  +    }
  +
  +    protected void movetoCurrPosition() {
  +        write(this.currentXPosition + " " + this.currentYPosition + " M");
  +    }
  +
  +    /**
  +     * set up the font info
  +     *
  +     * @param fontInfo the font info object to set up
  +     */
  +    public void setupFontInfo(FontInfo fontInfo)
  +        throws FOPException {
  +        /* use PDF's font setup to get PDF metrics */
  +        org.apache.fop.render.pdf.FontSetup.setup(fontInfo);
  +        this.fontInfo = fontInfo;
  +    }
  +
  +    protected void addFilledRect(int x, int y, int w, int h,
  +                                 ColorType col) {
  +        // XXX: cater for braindead, legacy -ve heights
  +        if (h < 0) {
  +           h = -h;
  +        }
  +
  +            write("newpath");
  +            write(x + " " + y + " " + w + " " + -h + " re");
  +            /*
  +            write(x + " " + y + " M");
  +            write(w + " 0 rlineto");
  +            write("0 " + (-h) + " rlineto");
  +            write((-w) + " 0 rlineto");
  +            write("0 " + h + " rlineto");
  +            write("closepath");
  +            */
  +            useColor(col);
  +            write("fill");
  +    }
  +
  +    /**
  +     * render a display space to PostScript
  +     *
  +     * @param space the space to render
  +     */
  +    public void renderDisplaySpace(DisplaySpace space) {
  +        // write("% --- DisplaySpace size="+space.getSize());
  +        this.currentYPosition -= space.getSize();
  +        movetoCurrPosition();
  +    }
  +
  +    /**
  +     * render a foreign object area
  +     */
  +    public void renderForeignObjectArea(ForeignObjectArea area) {
  +        // if necessary need to scale and align the content
  +        this.currentXPosition = this.currentXPosition + area.getXOffset();
  +        int plOffset = 0;
  +        Area parent = area.getParent();
  +        if (parent instanceof LineArea) {
  +            plOffset = ((LineArea)parent).getPlacementOffset();
  +        }
  +        this.currentYPosition += plOffset;
  +        area.getObject().render(this);
  +        this.currentXPosition += area.getEffectiveWidth();
  +        this.currentYPosition -= plOffset;
  +        movetoCurrPosition();
  +    }
  +
  +    /**
  +     * render an SVG area to PostScript
  +     *
  +     * @param area the area to render
  +     */
  +    public void renderSVGArea(SVGArea area) {
  +        int x = this.currentXPosition;
  +        int y = this.currentYPosition;
  +        renderSVGDocument(area.getSVGDocument(), x, y, area.getFontState());
  +    }
  +
  +
  +    /**
  +     * render SVG document to PostScript
  +     *
  +     * @param doc  the document to render
  +     * @param x    the x offset
  +     * @param y    the y offset
  +     * @param fs   the fontstate to use
  +     */
  +    protected void renderSVGDocument(Document doc, int x, int y,
  +            FontState fs) {
  +        org.apache.fop.svg.SVGUserAgent userAgent
  +            = new org.apache.fop.svg.SVGUserAgent(new AffineTransform());
  +        userAgent.setLogger(log);
  +
  +        GVTBuilder builder = new GVTBuilder();
  +        BridgeContext ctx = new BridgeContext(userAgent);
  +
  +        GraphicsNode root;
  +        try {
  +            root = builder.build(ctx, doc);
  +        } catch (Exception e) {
  +            log.error("svg graphic could not be built: "
  +                                   + e.getMessage(), e);
  +            return;
  +        }
  +        // get the 'width' and 'height' attributes of the SVG document
  +        float w = (float)ctx.getDocumentSize().getWidth() * 1000f;
  +        float h = (float)ctx.getDocumentSize().getHeight() * 1000f;
  +
  +        //log.debug("drawing SVG image: "+x+"/"+y+" "+w+"/"+h);
  +
  +        ctx = null;
  +        builder = null;
  +
  +        float sx = 1, sy = -1;
  +        int xOffset = x, yOffset = y;
  +
  +        comment("% --- SVG Area");
  +        write("gsave");
  +        if (w != 0 && h != 0) {
  +            write("newpath");
  +            write(x + " " + y + " M");
  +            write((x + w) + " " + y + " rlineto");
  +            write((x + w) + " " + (y - h) + " rlineto");
  +            write(x + " " + (y - h) + " rlineto");
  +            write("closepath");
  +            write("clippath");
  +        }
  +        // transform so that the coordinates (0,0) is from the top left
  +        // and positive is down and to the right. (0,0) is where the
  +        // viewBox puts it.
  +        write(xOffset + " " + yOffset + " translate");
  +        write(sx + " " + sy + " scale");
  +
  +        PSGraphics2D graphics = new PSGraphics2D(false, fs,
  +                                this, currentFontName,
  +                                currentFontSize,
  +                                currentXPosition,
  +                                currentYPosition);
  +        graphics.setGraphicContext(new 
org.apache.batik.ext.awt.g2d.GraphicContext());
  +        try {
  +            root.paint(graphics);
  +        } catch (Exception e) {
  +            log.error("svg graphic could not be rendered: "
  +                                   + e.getMessage(), e);
  +        }
  +
  +        write("grestore");
  +
  +        comment("% --- SVG Area end");
  +    }
  +
  +    /**
  +     * Renders an image, scaling it to the given width and height.
  +     * If the scaled width and height is the same intrinsic size
  +     * of the image, the image is not scaled.
  +     *
  +     * @param x the x position of left edge in millipoints
  +     * @param y the y position of top edge in millipoints
  +     * @param w the width in millipoints
  +     * @param h the height in millipoints
  +     * @param image the image to be rendered
  +     * @param fs the font state to use when rendering text
  +     *           in non-bitmapped images.
  +     */
  +    protected void drawImageScaled(int x, int y, int w, int h,
  +                   FopImage image,
  +                   FontState fs) {
  +        //log.debug("drawing scaled image: "+x+"/"+y+" "+w+"/"+h);
  +        if (image instanceof SVGImage) {
  +            try {
  +                renderSVGDocument(((SVGImage)image).getSVGDocument(), x, y, fs);
  +            } catch (FopImageException e) {
  +                log.error("Error rendering SVG image", e);
  +            }
  +        } else if (image instanceof EPSImage) {
  +            renderEPS(image, x, y, w, h);
  +        } else {
  +            renderBitmap(image, x, y, w, h);
  +        }
  +    }
  +
  +    /**
  +     * Renders an image, clipping it as specified.
  +     *
  +     * @param x the x position of left edge in millipoints.
  +     * @param y the y position of top edge in millipoints.
  +     * @param clipX the left edge of the clip in millipoints
  +     * @param clipY the top edge of the clip in millipoints
  +     * @param clipW the clip width in millipoints
  +     * @param clipH the clip height in millipoints
  +     * @param image the image to be rendered
  +     * @param fs the font state to use when rendering text
  +     *           in non-bitmapped images.
  +     */
  +    protected void drawImageClipped(int x, int y,
  +                    int clipX, int clipY,
  +                    int clipW, int clipH,
  +                    FopImage image,
  +                    FontState fs) {
  +        //log.debug("drawing clipped image: "+x+"/"+y+" "+clipX+"/"+clipY+" 
"+clipW+"/"+clipH);
  +        write("gsave");
  +        write(clipX + " " + clipY + " " + clipW + " " + clipH + " re");
  +        write("clippath");
  +
  +        try {
  +            int w = image.getWidth() * 1000;
  +            int h = image.getHeight() * 1000;
  +
  +            drawImageScaled(x, y, w, h, image, fs);
  +        } catch (FopImageException e) {
  +            log.error("Error getting image extents", e);
  +        }
  +        write("grestore");
  +    }
  +
  +    public void renderEPS(FopImage img, int x, int y, int w, int h) {
  +        try {
  +            EPSImage eimg = (EPSImage)img;
  +            int[] bbox = eimg.getBBox();
  +            int bboxw = bbox[2] - bbox[0];
  +            int bboxh = bbox[3] - bbox[1];
  +
  +
  +            write("%%BeginDocument: " + eimg.getDocName());
  +            write("BeginEPSF");
  +
  +            write(x + " " + (y - h) + " translate");
  +            write("0.0 rotate");
  +            write((long)(w/bboxw) + " " + (long)(h/bboxh) + " scale");
  +            write(-bbox[0] + " " + (-bbox[1]) + " translate");
  +            write(bbox[0] + " " + bbox[1] + " " + bboxw + " " + bboxh + " 
rectclip");
  +            write("newpath");
  +            out.writeByteArr(img.getBitmaps());
  +            write("%%EndDocument");
  +            write("EndEPSF");
  +            write("");
  +        } catch (Exception e) {
  +            e.printStackTrace();
  +            log.error("PSRenderer.renderImageArea(): Error rendering bitmap ("
  +                                   + e.getMessage() + ")", e);
  +        }
  +    }
  +
  +    public void renderBitmap(FopImage img, int x, int y, int w, int h) {
  +        try {
  +            boolean iscolor = img.getColorSpace().getColorSpace()
  +                              != ColorSpace.DEVICE_GRAY;
  +            byte[] imgmap = img.getBitmaps();
  +
  +            write("gsave");
  +            if (img.getColorSpace().getColorSpace() == ColorSpace.DEVICE_CMYK)
  +                write("/DeviceCMYK setcolorspace");
  +            else
  +                write("/DeviceRGB setcolorspace");
  +
  +            write(x + " " + (y - h) + " translate");
  +            write(w + " " + h + " scale");
  +            write("<<");
  +            write("  /ImageType 1");
  +            write("  /Width " + img.getWidth());
  +            write("  /Height " + img.getHeight());
  +            write("  /BitsPerComponent 8");
  +            if (img.getColorSpace().getColorSpace() == ColorSpace.DEVICE_CMYK) {
  +                if (img.invertImage())
  +                    write("  /Decode [1 0 1 0 1 0 1 0]");
  +                else
  +                    write("  /Decode [0 1 0 1 0 1 0 1]");
  +            } else if (iscolor) {
  +                write("  /Decode [0 1 0 1 0 1]");
  +            } else {
  +                write("  /Decode [0 1]");
  +            }
  +            // Setup scanning for left-to-right and top-to-bottom
  +            write("  /ImageMatrix [" + img.getWidth() + " 0 0 -"
  +                  + img.getHeight() + " 0 " + img.getHeight() + "]");
  +
  +            if (img instanceof JpegImage) {
  +                write("  /DataSource currentfile /ASCII85Decode filter /DCTDecode 
filter");
  +            } else {
  +                if (this.psLevel >= 3) {
  +                    write("  /DataSource currentfile /ASCII85Decode filter 
/FlateDecode filter");
  +                } else {
  +                    write("  /DataSource currentfile /ASCII85Decode filter 
/RunLengthDecode filter");
  +                }
  +            }
  +            // write("  /DataSource currentfile /ASCIIHexDecode filter /FlateDecode 
filter");
  +            // write("  /DataSource currentfile /ASCIIHexDecode filter 
/RunLengthDecode filter");
  +            // write("  /DataSource currentfile /ASCIIHexDecode filter");
  +            // write("  /DataSource currentfile /ASCII85Decode filter");
  +            // write("  /DataSource currentfile /RunLengthDecode filter");
  +            write(">>");
  +            write("image");
  +
  +            /*
  +             * for (int y=0; y<img.getHeight(); y++) {
  +             * int indx = y * img.getWidth();
  +             * if (iscolor) indx*= 3;
  +             * for (int x=0; x<img.getWidth(); x++) {
  +             * if (iscolor) {
  +             * writeASCIIHex(imgmap[indx++] & 0xFF);
  +             * writeASCIIHex(imgmap[indx++] & 0xFF);
  +             * writeASCIIHex(imgmap[indx++] & 0xFF);
  +             * } else {
  +             * writeASCIIHex(imgmap[indx++] & 0xFF);
  +             * }
  +             * }
  +             * }
  +             */
  +            try {
  +                // imgmap[0] = 1;
  +                OutputStream out = this.out;
  +                out = new ASCII85OutputStream(out);
  +                if (!(img instanceof JpegImage)) {
  +                    if (this.psLevel >= 3) {
  +                        out = new FlateEncodeOutputStream(out);
  +                    } else {
  +                        out = new RunLengthEncodeOutputStream(out);
  +                    }
  +                }
  +                out.write(imgmap);
  +                ((Finalizable)out).finalizeStream();
  +            } catch (IOException e) {
  +                if (!ioTrouble)
  +                    e.printStackTrace();
  +                ioTrouble = true;
  +            }
  +
  +            write("");
  +            write("grestore");
  +        } catch (FopImageException e) {
  +            log.error("PSRenderer.renderImageArea(): Error rendering bitmap ("
  +                                   + e.getMessage() + ")", e);
  +        }
  +    }
  +
  +    /**
  +     * Render an image area.
  +     *
  +     * @param area the image area to render
  +     */
  +    public void renderImageArea(ImageArea area) {
  +        // adapted from contribution by BoBoGi
  +        int x = this.currentXPosition + area.getXOffset();
  +        int ploffset = 0;
  +        if (area.getParent() instanceof LineArea) {
  +            ploffset = ((LineArea)area.getParent()).getPlacementOffset();
  +        }
  +        int y = this.currentYPosition + ploffset;
  +        int w = area.getContentWidth();
  +        int h = area.getHeight();
  +
  +        //this.currentYPosition -= h;
  +        this.currentXPosition += w;
  +
  +        FopImage img = area.getImage();
  +
  +        if (img == null) {
  +            log.error("Error while loading image: area.getImage() is null");
  +        } else {
  +            drawImageScaled(x, y, w, h, img, area.getFontState());
  +        }
  +        movetoCurrPosition();
  +    }
  +
  +
  +    /**
  +     * render an image area to PostScript
  +     *
  +     * @param area the area to render
  +     */
  +     /*
  +    public void renderImageArea(ImageArea area) {
  +        int x = this.currentXPosition + area.getXOffset();
  +        int ploffset = 0;
  +        if (area.getParent() instanceof LineArea) {
  +            ploffset = ((LineArea)area.getParent()).getPlacementOffset();
  +        }
  +        int y = this.currentYPosition + ploffset;
  +        int w = area.getContentWidth();
  +        int h = area.getHeight();
  +        this.currentYPosition -= area.getHeight();
  +
  +        imagecount++;
  +        // if (imagecount!=4) return;
  +
  +        comment("% --- ImageArea");
  +        if (area.getImage() instanceof SVGImage) {
  +            renderSVGDocument(((SVGImage)area.getImage()).getSVGDocument(), x, y, 
area.getFontState());
  +        } else if (area.getImage() instanceof EPSImage) {
  +            renderEPS(area.getImage(), x, y, w, h);
  +        } else {
  +            renderBitmap(area.getImage(), x, y, w, h);
  +        }
  +        comment("% --- ImageArea end");
  +    }*/
  +
  +    /**
  +     * render an inline area to PostScript
  +     *
  +     * @param area the area to render
  +     */
  +    public void renderWordArea(WordArea area) {
  +        movetoCurrPosition();
  +        FontState fs = area.getFontState();
  +        String fontWeight = fs.getFontWeight();
  +        StringBuffer sb = new StringBuffer();
  +        String s;
  +        if (area.getPageNumberID()
  +                != null) {    // this text is a page number, so resolve it
  +            s = idReferences.getPageNumber(area.getPageNumberID());
  +            if (s == null) {
  +                s = "";
  +            }
  +        } else {
  +            s = area.getText();
  +        }
  +        int l = s.length();
  +
  +        for (int i = 0; i < l; i++) {
  +            char ch = s.charAt(i);
  +            char mch = fs.mapChar(ch);
  +            if (mch > 127) {
  +                sb = sb.append("\\" + Integer.toOctalString(mch));
  +            } else {
  +                String escape = "\\()[]{}";
  +                if (escape.indexOf(mch) >= 0) {
  +                    sb.append("\\");
  +                }
  +                sb = sb.append(mch);
  +            }
  +        }
  +
  +        String psString = null;
  +        if (area.getFontState().getLetterSpacing() > 0) {
  +            //float f = area.getFontState().getLetterSpacing() * 1000 / 
this.currentFontSize;
  +            float f = area.getFontState().getLetterSpacing();
  +            psString = (new StringBuffer().append(f).append(" 0.0 (").append(sb).
  +                        append(") A")).toString();
  +        } else {
  +            psString = (new StringBuffer("(").append(sb).append(") t")).toString();
  +        }
  +
  +
  +        // System.out.println("["+s+"] --> ["+sb.toString()+"]");
  +
  +        // comment("% --- InlineArea font-weight="+fontWeight+": " + sb.toString());
  +        useFont(fs.getFontName(), fs.getFontSize());
  +        useColor(area.getRed(), area.getGreen(), area.getBlue());
  +        if (area.getUnderlined() || area.getLineThrough()
  +                || area.getOverlined())
  +            write("ULS");
  +        write(psString);
  +        if (area.getUnderlined())
  +            write("ULE");
  +        if (area.getLineThrough())
  +            write("SOE");
  +        if (area.getOverlined())
  +            write("OLE");
  +        this.currentXPosition += area.getContentWidth();
  +    }
  +
  +    public void useFont(String name, int size) {
  +        if ((currentFontName != name) || (currentFontSize != size)) {
  +            write(name + " " + size + " F");
  +            currentFontName = name;
  +            currentFontSize = size;
  +        }
  +    }
  +
  +    /**
  +     * render an inline space to PostScript
  +     *
  +     * @param space the space to render
  +     */
  +    public void renderInlineSpace(InlineSpace space) {
  +        // write("% --- InlineSpace size="+space.getSize());
  +        if (space.getUnderlined() || space.getLineThrough()
  +                || space.getOverlined()) {
  +            //start textdeko
  +            movetoCurrPosition();
  +            write("ULS");
  +
  +            write(space.getSize() + " 0 RM");
  +
  +            //end textdeko
  +            if (space.getUnderlined())
  +                write("ULE");
  +            if (space.getLineThrough())
  +                write("SOE");
  +            if (space.getOverlined())
  +                write("OLE");
  +        }
  +        this.currentXPosition += space.getSize();
  +    }
  +
  +    /**
  +     * render a line area to PostScript
  +     *
  +     * @param area the area to render
  +     */
  +    public void renderLineArea(LineArea area) {
  +        int rx = this.currentAreaContainerXPosition + area.getStartIndent();
  +        int ry = this.currentYPosition;
  +        int w = area.getContentWidth();
  +        int h = area.getHeight();
  +
  +        this.currentYPosition -= area.getPlacementOffset();
  +        this.currentXPosition = rx;
  +
  +        int bl = this.currentYPosition;
  +        // method is identical to super method except next line
  +        movetoCurrPosition();
  +
  +        String fontWeight = area.getFontState().getFontWeight();
  +        //comment("% --- LineArea begin font-weight="+fontWeight);
  +        ArrayList children = area.getChildren();
  +        for (int i = 0; i < children.size(); i++) {
  +            Box b = (Box)children.get(i);
  +            this.currentYPosition = ry - area.getPlacementOffset();
  +            b.render(this);
  +        }
  +        //comment("% --- LineArea end");
  +
  +        this.currentYPosition = ry - h;
  +        this.currentXPosition = rx;
  +    }
  +
  +    /**
  +     * render a page to PostScript
  +     *
  +     * @param page the page to render
  +     */
  +    public void renderPage(Page page) {
  +        this.pagecount++;
  +        this.idReferences = page.getIDReferences();
  +
  +        write("%%Page: " + page.getNumber() + " " + page.getNumber());
  +        write("%%PageBoundingBox: 0 0 " +
  +                Math.round(page.getWidth() / 1000f) + " " +
  +                Math.round(page.getHeight() / 1000f));
  +        write("%%BeginPageSetup");
  +        write("FOPprocs begin");
  +        write("FOPFonts begin");
  +        write("0.001 0.001 scale");
  +        write("%%EndPageSetup");
  +        renderRegions(page);
  +        write("showpage");
  +        write("%%PageTrailer");
  +        write("%%EndPage"); //This is non-standard, but used by Adobe.
  +    }
  +
  +    /**
  +     * render a leader area to PostScript
  +     *
  +     * @param area the area to render
  +     */
  +    public void renderLeaderArea(LeaderArea area) {
  +        int rx = this.currentXPosition;
  +        int ry = this.currentYPosition;
  +        int w = area.getContentWidth();
  +        int th = area.getRuleThickness();
  +        int th2 = th / 2;
  +        int th3 = th / 3;
  +        int th4 = th / 4;
  +
  +        switch (area.getLeaderPattern()) {
  +        case LeaderPattern.SPACE:
  +            // NOP
  +
  +            break;
  +        case LeaderPattern.RULE:
  +            if (area.getRuleStyle() == RuleStyle.NONE)
  +                break;
  +            useColor(area.getRed(), area.getGreen(), area.getBlue());
  +            write("gsave");
  +            write("0 setlinecap");
  +            switch (area.getRuleStyle()) {
  +            case RuleStyle.DOTTED:
  +                write("newpath");
  +                write("[1000 3000] 0 setdash");
  +                write(th + " setlinewidth");
  +                write(rx + " " + ry + " M");
  +                write(w + " 0 rlineto");
  +                useColor(area.getRed(), area.getGreen(), area.getBlue());
  +                write("stroke");
  +                break;
  +            case RuleStyle.DASHED:
  +                write("newpath");
  +                write("[3000 3000] 0 setdash");
  +                write(th + " setlinewidth");
  +                write(rx + " " + ry + " M");
  +                write(w + " 0 rlineto");
  +                useColor(area.getRed(), area.getGreen(), area.getBlue());
  +                write("stroke");
  +                break;
  +            case RuleStyle.SOLID:
  +                write("newpath");
  +                write(th + " setlinewidth");
  +                write(rx + " " + ry + " M");
  +                write(w + " 0 rlineto");
  +                useColor(area.getRed(), area.getGreen(), area.getBlue());
  +                write("stroke");
  +                break;
  +            case RuleStyle.DOUBLE:
  +                write("newpath");
  +                write(th3 + " setlinewidth");
  +                write(rx + " " + (ry - th3) + " M");
  +                write(w + " 0 rlineto");
  +                write(rx + " " + (ry + th3) + " M");
  +                write(w + " 0 rlineto");
  +                useColor(area.getRed(), area.getGreen(), area.getBlue());
  +                write("stroke");
  +                break;
  +            case RuleStyle.GROOVE:
  +                write(th2 + " setlinewidth");
  +                write("newpath");
  +                write(rx + " " + (ry - th4) + " M");
  +                write(w + " 0 rlineto");
  +                useColor(area.getRed(), area.getGreen(), area.getBlue());
  +                write("stroke");
  +                write("newpath");
  +                write(rx + " " + (ry + th4) + " M");
  +                write(w + " 0 rlineto");
  +                useColor(1, 1, 1);    // white
  +                write("stroke");
  +                break;
  +            case RuleStyle.RIDGE:
  +                write(th2 + " setlinewidth");
  +                write("newpath");
  +                write(rx + " " + (ry - th4) + " M");
  +                write(w + " 0 rlineto");
  +                useColor(1, 1, 1);    // white
  +                write("stroke");
  +                write("newpath");
  +                write(rx + " " + (ry + th4) + " M");
  +                write(w + " 0 rlineto");
  +                useColor(area.getRed(), area.getGreen(), area.getBlue());
  +                write("stroke");
  +                break;
  +            }
  +            write("grestore");
  +            break;
  +        case LeaderPattern.DOTS:
  +            comment("% --- Leader dots NYI");
  +            log.error("Leader dots: Not yet implemented");
  +            break;
  +        case LeaderPattern.USECONTENT:
  +            comment("% --- Leader use-content NYI");
  +            log.error("Leader use-content: Not yet implemented");
  +            break;
  +        }
  +        this.currentXPosition += area.getContentWidth();
  +        write(area.getContentWidth() + " 0 RM");
  +    }
  +
  +    protected void doFrame(Area area) {
  +        int w, h;
  +        int rx = this.currentAreaContainerXPosition;
  +        w = area.getContentWidth();
  +        BorderAndPadding bap = area.getBorderAndPadding();
  +
  +        if (area instanceof BlockArea)
  +            rx += ((BlockArea)area).getStartIndent();
  +
  +        h = area.getContentHeight();
  +        int ry = this.currentYPosition;
  +
  +        rx = rx - area.getPaddingLeft();
  +        ry = ry + area.getPaddingTop();
  +        w = w + area.getPaddingLeft() + area.getPaddingRight();
  +        h = h + area.getPaddingTop() + area.getPaddingBottom();
  +
  +        rx = rx - area.getBorderLeftWidth();
  +        ry = ry + area.getBorderTopWidth();
  +        w = w + area.getBorderLeftWidth() + area.getBorderRightWidth();
  +        h = h + area.getBorderTopWidth() + area.getBorderBottomWidth();
  +
  +        doBackground(area, rx, ry, w, h);
  +
  +        if (area.getBorderTopWidth() != 0) {
  +            write("newpath");
  +            write(rx + " " + ry + " M");
  +            write(w + " 0 rlineto");
  +            write(area.getBorderTopWidth() + " setlinewidth");
  +            write("0 setlinecap");
  +            useColor(bap.getBorderColor(BorderAndPadding.TOP));
  +            write("stroke");
  +        }
  +        if (area.getBorderLeftWidth() != 0) {
  +            write("newpath");
  +            write(rx + " " + ry + " M");
  +            write("0 " + (-h) + " rlineto");
  +            write(area.getBorderLeftWidth() + " setlinewidth");
  +            write("0 setlinecap");
  +            useColor(bap.getBorderColor(BorderAndPadding.LEFT));
  +            write("stroke");
  +        }
  +        if (area.getBorderRightWidth() != 0) {
  +            write("newpath");
  +            write((rx + w) + " " + ry + " M");
  +            write("0 " + (-h) + " rlineto");
  +            write(area.getBorderRightWidth() + " setlinewidth");
  +            write("0 setlinecap");
  +            useColor(bap.getBorderColor(BorderAndPadding.RIGHT));
  +            write("stroke");
  +        }
  +        if (area.getBorderBottomWidth() != 0) {
  +            write("newpath");
  +            write(rx + " " + (ry - h) + " M");
  +            write(w + " 0 rlineto");
  +            write(area.getBorderBottomWidth() + " setlinewidth");
  +            write("0 setlinecap");
  +            useColor(bap.getBorderColor(BorderAndPadding.BOTTOM));
  +            write("stroke");
  +        }
  +    }
  +
  +    private void useColor(ColorType col) {
  +        useColor(col.red(), col.green(), col.blue());
  +    }
  +
  +    private void useColor(float red, float green, float blue) {
  +        if ((red != currRed) || (green != currGreen) || (blue != currBlue)) {
  +            write(red + " " + green + " " + blue + " setrgbcolor");
  +            currRed = red;
  +            currGreen = green;
  +            currBlue = blue;
  +        }
  +    }
  +
  +    /**
  +      Default start renderer method. This would
  +      normally be overridden. ([EMAIL PROTECTED]).
  +    */
  +    public void startRenderer(OutputStream outputStream)
  +    throws IOException {
  +        log.debug("rendering areas to PostScript");
  +
  +        this.pagecount = 0;
  +        this.out = new PSStream(outputStream);
  +        write("%!PS-Adobe-3.0");
  +        if (this.producer == null) {
  +            this.producer = org.apache.fop.apps.Version.getVersion();
  +        }
  +        write("%%Creator: "+this.producer);
  +        write("%%Pages: (atend)");
  +        write("%%DocumentProcessColors: Black");
  +        write("%%DocumentSuppliedResources: procset FOPFonts");
  +        write("%%EndComments");
  +        write("%%BeginDefaults");
  +        write("%%EndDefaults");
  +        write("%%BeginProlog");
  +        write("%%EndProlog");
  +        write("%%BeginSetup");
  +        writeProcs();
  +        writeFontDict(fontInfo);
  +
  +        /* Write proc for including EPS */
  +        write("%%BeginResource: procset EPSprocs");
  +        write("%%Title: EPS encapsulation procs");
  +
  +        write("/BeginEPSF { %def");
  +        write("/b4_Inc_state save def         % Save state for cleanup");
  +        write("/dict_count countdictstack def % Count objects on dict stack");
  +        write("/op_count count 1 sub def      % Count objects on operand stack");
  +        write("userdict begin                 % Push userdict on dict stack");
  +        write("/showpage { } def              % Redefine showpage, { } = null 
proc");
  +        write("0 setgray 0 setlinecap         % Prepare graphics state");
  +        write("1 setlinewidth 0 setlinejoin");
  +        write("10 setmiterlimit [ ] 0 setdash newpath");
  +        write("/languagelevel where           % If level not equal to 1 then");
  +        write("{pop languagelevel             % set strokeadjust and");
  +        write("1 ne                           % overprint to their defaults.");
  +        write("{false setstrokeadjust false setoverprint");
  +        write("} if");
  +        write("} if");
  +        write("} bind def");
  +
  +        write("/EndEPSF { %def");
  +        write("count op_count sub {pop} repeat            % Clean up stacks");
  +        write("countdictstack dict_count sub {end} repeat");
  +        write("b4_Inc_state restore");
  +        write("} bind def");
  +        write("%%EndResource");
  +
  +        write("%%EndSetup");
  +    }
  +
  +    /**
  +      Default stop renderer method. This would
  +      normally be overridden. ([EMAIL PROTECTED]).
  +    */
  +    public void stopRenderer(OutputStream outputStream)
  +    throws IOException {
  +        write("%%Trailer");
  +        write("%%Pages: "+this.pagecount);
  +        write("%%EOF");
  +        this.out.flush();
  +        log.debug("written out PostScript");
  +    }
  +
  +    public void render(Page page, OutputStream outputStream) {
  +        this.renderPage(page);
  +    }
  +}
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.1   +0 -0      
xml-fop/src/org/apache/fop/render/ps/RunLengthEncodeOutputStream.java
  
  Index: RunLengthEncodeOutputStream.java
  ===================================================================
  RCS file: 
/home/cvs/xml-fop/src/org/apache/fop/render/ps/RunLengthEncodeOutputStream.java,v
  retrieving revision 1.1
  retrieving revision 1.1.2.1
  diff -u -r1.1 -r1.1.2.1
  
  
  

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

Reply via email to