jeremias    2003/01/27 01:17:05

  Modified:    src/org/apache/fop/render/ps PSGraphics2D.java
                        PSRenderer.java
  Added:       src/org/apache/fop/render/ps DSCConstants.java
                        PSGenerator.java PSProcSets.java
  Removed:     src/org/apache/fop/render/ps PSStream.java
  Log:
  First step at bringing back the PostScript renderer. Basic text works to a
  certain degree. Well, it compiles. :-)
  
  Started to factor out PS generation for cleaner separation of PS transcoder and PS 
renderer
  Separation of PostScript procsets so they don't clutter the code of PSRenderer.
  
  Revision  Changes    Path
  1.8       +288 -257  xml-fop/src/org/apache/fop/render/ps/PSGraphics2D.java
  
  Index: PSGraphics2D.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/render/ps/PSGraphics2D.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- PSGraphics2D.java 8 Jan 2003 14:03:35 -0000       1.7
  +++ PSGraphics2D.java 27 Jan 2003 09:17:04 -0000      1.8
  @@ -37,13 +37,11 @@
   import java.awt.image.Raster;
   import java.awt.image.RenderedImage;
   import java.awt.image.renderable.RenderableImage;
  +import java.io.IOException;
   
   // FOP
   import org.apache.fop.layout.FontInfo;
   import org.apache.fop.layout.FontState;
  -import org.apache.fop.pdf.PDFColor;
  -//import org.apache.fop.pdf.PDFColorSpace;
  -import org.apache.fop.pdf.PDFNumber;
   
   // Batik
   import org.apache.batik.ext.awt.g2d.AbstractGraphics2D;
  @@ -67,9 +65,9 @@
       private boolean standalone = false;
   
       /**
  -     * the PDF Document being created
  +     * the PostScript genertaor being created
        */
  -    protected PSRenderer psRenderer;
  +    protected PSGenerator gen;
   
       /** Currently valid FontState */
       protected FontState fontState;
  @@ -97,7 +95,7 @@
       /**
        * the current colour for use in svg
        */
  -    protected PDFColor currentColour = new PDFColor(0, 0, 0);
  +    protected Color currentColour = new Color(0, 0, 0);
   
       /** FontInfo containing all available fonts */
       protected FontInfo fontInfo;
  @@ -106,17 +104,17 @@
        * Create a new Graphics2D that generates PostScript code.
        * @param textAsShapes True if text should be rendered as graphics
        * @param fs currently valid FontState object
  -     * @param ren PostScript renderer
  +     * @param gen PostScript generator to use for output
        * @param font current font name
        * @param size current font size
        * @param xpos current x pos
        * @param ypos current y pos
        * @see 
org.apache.batik.ext.awt.g2d.AbstractGraphics2D#AbstractGraphics2D(boolean)
        */
  -    public PSGraphics2D(boolean textAsShapes, FontState fs, PSRenderer ren,
  +    public PSGraphics2D(boolean textAsShapes, FontState fs, PSGenerator gen,
                           String font, int size, int xpos, int ypos) {
           super(textAsShapes);
  -        psRenderer = ren;
  +        this.gen = gen;
           currentFontName = font;
           currentFontSize = size;
           currentYPosition = ypos;
  @@ -159,6 +157,14 @@
       }
   
       /**
  +     * Central handler for IOExceptions for this class.
  +     * @param ioe IOException to handle
  +     */
  +    protected void handleIOException(IOException ioe) {
  +        ioe.printStackTrace();
  +    }
  +
  +    /**
        * Draws as much of the specified image as is currently available.
        * The image is drawn with its top-left corner at
        * (<i>x</i>,&nbsp;<i>y</i>) in this graphics context's coordinate
  @@ -441,7 +447,7 @@
        */
       public void dispose() {
           // System.out.println("dispose");
  -        psRenderer = null;
  +        this.gen = null;
           fontState = null;
           currentFontName = null;
           currentColour = null;
  @@ -465,58 +471,62 @@
        * @see #setComposite
        */
       public void draw(Shape s) {
  -        // System.out.println("draw(Shape)");
  -        psRenderer.write("gsave");
  -        Shape imclip = getClip();
  -        writeClip(imclip);
  -        Color c = getColor();
  -        psRenderer.write(c.getRed() + " " + c.getGreen() + " " + c.getBlue()
  -                         + " setrgbcolor");
  -
  -        applyPaint(getPaint(), false);
  -        applyStroke(getStroke());
  -
  -        psRenderer.write("newpath");
  -        PathIterator iter = s.getPathIterator(getTransform());
  -        while (!iter.isDone()) {
  -            double vals[] = new double[6];
  -            int type = iter.currentSegment(vals);
  -            switch (type) {
  -            case PathIterator.SEG_CUBICTO:
  -                psRenderer.write(PDFNumber.doubleOut(1000 * vals[0]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[1]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[2]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[3]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[4]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[5])
  -                                 + " curveto");
  -                break;
  -            case PathIterator.SEG_LINETO:
  -                psRenderer.write(PDFNumber.doubleOut(1000 * vals[0]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[1])
  -                                 + " lineto");
  -                break;
  -            case PathIterator.SEG_MOVETO:
  -                psRenderer.write(PDFNumber.doubleOut(1000 * vals[0]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[1])
  -                                 + " M");
  -                break;
  -            case PathIterator.SEG_QUADTO:
  -                // psRenderer.write((1000 * PDFNumber.doubleOut(vals[0])) +
  -                // " " + (1000 * PDFNumber.doubleOut(vals[1])) + " " +
  -                // (1000 * PDFNumber.doubleOut(vals[2])) + " " +
  -                // (1000 * PDFNumber.doubleOut(vals[3])) + " y\n");
  -                break;
  -            case PathIterator.SEG_CLOSE:
  -                psRenderer.write("closepath");
  -                break;
  -            default:
  -                break;
  +        try {
  +            // System.out.println("draw(Shape)");
  +            gen.writeln("gsave");
  +            Shape imclip = getClip();
  +            writeClip(imclip);
  +            Color c = getColor();
  +            gen.writeln(c.getRed() + " " + c.getGreen() + " " + c.getBlue()
  +                             + " setrgbcolor");
  +            
  +            applyPaint(getPaint(), false);
  +            applyStroke(getStroke());
  +            
  +            gen.writeln("newpath");
  +            PathIterator iter = s.getPathIterator(getTransform());
  +            while (!iter.isDone()) {
  +                double vals[] = new double[6];
  +                int type = iter.currentSegment(vals);
  +                switch (type) {
  +                case PathIterator.SEG_CUBICTO:
  +                    gen.writeln(gen.formatDouble(1000 * vals[0]) + " "
  +                              + gen.formatDouble(1000 * vals[1]) + " "
  +                              + gen.formatDouble(1000 * vals[2]) + " "
  +                              + gen.formatDouble(1000 * vals[3]) + " "
  +                              + gen.formatDouble(1000 * vals[4]) + " "
  +                              + gen.formatDouble(1000 * vals[5])
  +                              + " curveto");
  +                    break;
  +                case PathIterator.SEG_LINETO:
  +                    gen.writeln(gen.formatDouble(1000 * vals[0]) + " "
  +                              + gen.formatDouble(1000 * vals[1])
  +                              + " lineto");
  +                    break;
  +                case PathIterator.SEG_MOVETO:
  +                    gen.writeln(gen.formatDouble(1000 * vals[0]) + " "
  +                              + gen.formatDouble(1000 * vals[1])
  +                              + " M");
  +                    break;
  +                case PathIterator.SEG_QUADTO:
  +                    // psRenderer.write((1000 * PDFNumber.doubleOut(vals[0])) +
  +                    // " " + (1000 * PDFNumber.doubleOut(vals[1])) + " " +
  +                    // (1000 * PDFNumber.doubleOut(vals[2])) + " " +
  +                    // (1000 * PDFNumber.doubleOut(vals[3])) + " y\n");
  +                    break;
  +                case PathIterator.SEG_CLOSE:
  +                    gen.writeln("closepath");
  +                    break;
  +                default:
  +                    break;
  +                }
  +                iter.next();
               }
  -            iter.next();
  +            doDrawing(false, true, false);
  +            gen.writeln("grestore");
  +        } catch (IOException ioe) {
  +            handleIOException(ioe);
           }
  -        doDrawing(false, true, false);
  -        psRenderer.write("grestore");
       }
   
       /**
  @@ -524,47 +534,51 @@
        * @param s Shape defining the clipping region
        */
       protected void writeClip(Shape s) {
  -        PathIterator iter = s.getPathIterator(getTransform());
  -        psRenderer.write("newpath");
  -        while (!iter.isDone()) {
  -            double vals[] = new double[6];
  -            int type = iter.currentSegment(vals);
  -            switch (type) {
  -            case PathIterator.SEG_CUBICTO:
  -                psRenderer.write(PDFNumber.doubleOut(1000 * vals[0]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[1]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[2]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[3]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[4]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[5])
  -                                 + " curveto");
  -                break;
  -            case PathIterator.SEG_LINETO:
  -                psRenderer.write(PDFNumber.doubleOut(1000 * vals[0]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[1])
  -                                 + " lineto");
  -                break;
  -            case PathIterator.SEG_MOVETO:
  -                psRenderer.write(PDFNumber.doubleOut(1000 * vals[0]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[1])
  -                                 + " M");
  -                break;
  -            case PathIterator.SEG_QUADTO:
  -                // psRenderer.write(1000 * PDFNumber.doubleOut(vals[0]) +
  -                // " " + 1000 * PDFNumber.doubleOut(vals[1]) + " " +
  -                // 1000 * PDFNumber.doubleOut(vals[2]) + " " +
  -                // 1000 * PDFNumber.doubleOut(vals[3]) + " y\n");
  -                break;
  -            case PathIterator.SEG_CLOSE:
  -                psRenderer.write("closepath");
  -                break;
  -            default:
  -                break;
  +        try {
  +            PathIterator iter = s.getPathIterator(getTransform());
  +            gen.writeln("newpath");
  +            while (!iter.isDone()) {
  +                double vals[] = new double[6];
  +                int type = iter.currentSegment(vals);
  +                switch (type) {
  +                case PathIterator.SEG_CUBICTO:
  +                    gen.writeln(gen.formatDouble(1000 * vals[0]) + " "
  +                              + gen.formatDouble(1000 * vals[1]) + " "
  +                              + gen.formatDouble(1000 * vals[2]) + " "
  +                              + gen.formatDouble(1000 * vals[3]) + " "
  +                              + gen.formatDouble(1000 * vals[4]) + " "
  +                              + gen.formatDouble(1000 * vals[5])
  +                              + " curveto");
  +                    break;
  +                case PathIterator.SEG_LINETO:
  +                    gen.writeln(gen.formatDouble(1000 * vals[0]) + " "
  +                              + gen.formatDouble(1000 * vals[1])
  +                              + " lineto");
  +                    break;
  +                case PathIterator.SEG_MOVETO:
  +                    gen.writeln(gen.formatDouble(1000 * vals[0]) + " "
  +                              + gen.formatDouble(1000 * vals[1])
  +                              + " M");
  +                    break;
  +                case PathIterator.SEG_QUADTO:
  +                    // psRenderer.write(1000 * PDFNumber.doubleOut(vals[0]) +
  +                    // " " + 1000 * PDFNumber.doubleOut(vals[1]) + " " +
  +                    // 1000 * PDFNumber.doubleOut(vals[2]) + " " +
  +                    // 1000 * PDFNumber.doubleOut(vals[3]) + " y\n");
  +                    break;
  +                case PathIterator.SEG_CLOSE:
  +                    gen.writeln("closepath");
  +                    break;
  +                default:
  +                    break;
  +                }
  +                iter.next();
               }
  -            iter.next();
  +            // clip area
  +            gen.writeln("clippath");
  +        } catch (IOException ioe) {
  +            handleIOException(ioe);
           }
  -        // clip area
  -        psRenderer.write("clippath");
       }
   
       /**
  @@ -609,10 +623,10 @@
   
               List someColors = new java.util.ArrayList();
   
  -            PDFColor color1 = new PDFColor(c1.getRed(), c1.getGreen(),
  +            Color color1 = new Color(c1.getRed(), c1.getGreen(),
                                              c1.getBlue());
               someColors.add(color1);
  -            PDFColor color2 = new PDFColor(c2.getRed(), c2.getGreen(),
  +            Color color2 = new Color(c2.getRed(), c2.getGreen(),
                                              c2.getBlue());
               someColors.add(color2);
   
  @@ -627,54 +641,56 @@
        * @param stroke Stroke object to use
        */
       protected void applyStroke(Stroke stroke) {
  -        if (stroke instanceof BasicStroke) {
  -            BasicStroke bs = (BasicStroke)stroke;
  -
  -            float[] da = bs.getDashArray();
  -            if (da != null) {
  -                psRenderer.write("[");
  -                for (int count = 0; count < da.length; count++) {
  -                    psRenderer.write("" + (1000 * (int)da[count]));
  -                    if (count < da.length - 1) {
  -                        psRenderer.write(" ");
  +        try {
  +            if (stroke instanceof BasicStroke) {
  +                BasicStroke bs = (BasicStroke)stroke;
  +            
  +                float[] da = bs.getDashArray();
  +                if (da != null) {
  +                    gen.writeln("[");
  +                    for (int count = 0; count < da.length; count++) {
  +                        gen.writeln("" + (1000 * (int)da[count]));
  +                        if (count < da.length - 1) {
  +                            gen.writeln(" ");
  +                        }
                       }
  +                    gen.writeln("] ");
  +                    float offset = bs.getDashPhase();
  +                    gen.writeln((1000 * (int)offset) + " setdash");
                   }
  -                psRenderer.write("] ");
  -                float offset = bs.getDashPhase();
  -                psRenderer.write((1000 * (int)offset) + " setdash");
  -            }
  -            int ec = bs.getEndCap();
  -            switch (ec) {
  -            case BasicStroke.CAP_BUTT:
  -                psRenderer.write(0 + " setlinecap");
  -                break;
  -            case BasicStroke.CAP_ROUND:
  -                psRenderer.write(1 + " setlinecap");
  -                break;
  -            case BasicStroke.CAP_SQUARE:
  -                psRenderer.write(2 + " setlinecap");
  -                break;
  -            }
  -
  -            int lj = bs.getLineJoin();
  -            switch (lj) {
  -            case BasicStroke.JOIN_MITER:
  -                psRenderer.write(0 + " setlinejoin");
  -                break;
  -            case BasicStroke.JOIN_ROUND:
  -                psRenderer.write(1 + " setlinejoin");
  -                break;
  -            case BasicStroke.JOIN_BEVEL:
  -                psRenderer.write(2 + " setlinejoin");
  -                break;
  +                int ec = bs.getEndCap();
  +                switch (ec) {
  +                case BasicStroke.CAP_BUTT:
  +                    gen.writeln(0 + " setlinecap");
  +                    break;
  +                case BasicStroke.CAP_ROUND:
  +                    gen.writeln(1 + " setlinecap");
  +                    break;
  +                case BasicStroke.CAP_SQUARE:
  +                    gen.writeln(2 + " setlinecap");
  +                    break;
  +                }
  +            
  +                int lj = bs.getLineJoin();
  +                switch (lj) {
  +                case BasicStroke.JOIN_MITER:
  +                    gen.writeln("0 setlinejoin");
  +                    break;
  +                case BasicStroke.JOIN_ROUND:
  +                    gen.writeln("1 setlinejoin");
  +                    break;
  +                case BasicStroke.JOIN_BEVEL:
  +                    gen.writeln("2 setlinejoin");
  +                    break;
  +                }
  +                float lw = bs.getLineWidth();
  +                gen.writeln(gen.formatDouble(1000 * lw) + " setlinewidth");
  +            
  +                float ml = bs.getMiterLimit();
  +                gen.writeln(gen.formatDouble(1000 * ml) + " setmiterlimit");
               }
  -            float lw = bs.getLineWidth();
  -            psRenderer.write(PDFNumber.doubleOut(1000 * lw)
  -                             + " setlinewidth");
  -
  -            float ml = bs.getMiterLimit();
  -            psRenderer.write(PDFNumber.doubleOut(1000 * ml)
  -                             + " setmiterlimit");
  +        } catch (IOException ioe) {
  +            handleIOException(ioe);
           }
       }
   
  @@ -763,28 +779,32 @@
        * @see #setClip
        */
       public void drawString(String s, float x, float y) {
  -        System.out.println("drawString(String)");
  -        psRenderer.write("BT");
  -        Shape imclip = getClip();
  -        writeClip(imclip);
  -        Color c = getColor();
  -        psRenderer.write(c.getRed() + " " + c.getGreen() + " " + c.getBlue()
  -                         + " setrgbcolor");
  -
  -        AffineTransform trans = getTransform();
  -        trans.translate(x, y);
  -        double[] vals = new double[6];
  -        trans.getMatrix(vals);
  -
  -        psRenderer.write(PDFNumber.doubleOut(vals[0]) + " "
  -                         + PDFNumber.doubleOut(vals[1]) + " "
  -                         + PDFNumber.doubleOut(vals[2]) + " "
  -                         + PDFNumber.doubleOut(vals[3]) + " "
  -                         + PDFNumber.doubleOut(vals[4]) + " "
  -                         + PDFNumber.doubleOut(vals[5]) + " "
  -                         + PDFNumber.doubleOut(vals[6]) + " Tm [" + s + "]");
  -
  -        psRenderer.write("ET");
  +        try {
  +            System.out.println("drawString(String)");
  +            gen.writeln("BT");
  +            Shape imclip = getClip();
  +            writeClip(imclip);
  +            Color c = getColor();
  +            gen.writeln(c.getRed() + " " + c.getGreen() + " " + c.getBlue()
  +                             + " setrgbcolor");
  +            
  +            AffineTransform trans = getTransform();
  +            trans.translate(x, y);
  +            double[] vals = new double[6];
  +            trans.getMatrix(vals);
  +            
  +            gen.writeln(gen.formatDouble(vals[0]) + " "
  +                      + gen.formatDouble(vals[1]) + " "
  +                      + gen.formatDouble(vals[2]) + " "
  +                      + gen.formatDouble(vals[3]) + " "
  +                      + gen.formatDouble(vals[4]) + " "
  +                      + gen.formatDouble(vals[5]) + " "
  +                      + gen.formatDouble(vals[6]) + " Tm [" + s + "]");
  +            
  +            gen.writeln("ET");
  +        } catch (IOException ioe) {
  +            handleIOException(ioe);
  +        }
       }
   
       /**
  @@ -814,38 +834,42 @@
        */
       public void drawString(AttributedCharacterIterator iterator, float x,
                              float y) {
  -        System.err.println("drawString(AttributedCharacterIterator)");
  -
  -        psRenderer.write("BT");
  -        Shape imclip = getClip();
  -        writeClip(imclip);
  -        Color c = getColor();
  -        currentColour = new PDFColor(c.getRed(), c.getGreen(), c.getBlue());
  -        psRenderer.write(currentColour.getColorSpaceOut(true));
  -        c = getBackground();
  -        PDFColor col = new PDFColor(c.getRed(), c.getGreen(), c.getBlue());
  -        psRenderer.write(col.getColorSpaceOut(false));
  -
  -        AffineTransform trans = getTransform();
  -        trans.translate(x, y);
  -        double[] vals = new double[6];
  -        trans.getMatrix(vals);
  -
  -        for (char ch = iterator.first(); ch != CharacterIterator.DONE;
  -                ch = iterator.next()) {
  -            //Map attr = iterator.getAttributes();
  -
  -            psRenderer.write(PDFNumber.doubleOut(vals[0]) + " "
  -                             + PDFNumber.doubleOut(vals[1]) + " "
  -                             + PDFNumber.doubleOut(vals[2]) + " "
  -                             + PDFNumber.doubleOut(vals[3]) + " "
  -                             + PDFNumber.doubleOut(vals[4]) + " "
  -                             + PDFNumber.doubleOut(vals[5]) + " "
  -                             + PDFNumber.doubleOut(vals[6]) + " Tm [" + ch
  -                             + "]");
  +        try {
  +            System.err.println("drawString(AttributedCharacterIterator)");
  +            
  +            gen.writeln("BT");
  +            Shape imclip = getClip();
  +            writeClip(imclip);
  +            Color c = getColor();
  +            currentColour = new Color(c.getRed(), c.getGreen(), c.getBlue());
  +            //gen.writeln(currentColour.getColorSpaceOut(true));
  +            c = getBackground();
  +            Color col = new Color(c.getRed(), c.getGreen(), c.getBlue());
  +            //gen.writeln(col.getColorSpaceOut(false));
  +            
  +            AffineTransform trans = getTransform();
  +            trans.translate(x, y);
  +            double[] vals = new double[6];
  +            trans.getMatrix(vals);
  +            
  +            for (char ch = iterator.first(); ch != CharacterIterator.DONE;
  +                    ch = iterator.next()) {
  +                //Map attr = iterator.getAttributes();
  +            
  +                gen.writeln(gen.formatDouble(vals[0]) + " "
  +                          + gen.formatDouble(vals[1]) + " "
  +                          + gen.formatDouble(vals[2]) + " "
  +                          + gen.formatDouble(vals[3]) + " "
  +                          + gen.formatDouble(vals[4]) + " "
  +                          + gen.formatDouble(vals[5]) + " "
  +                          + gen.formatDouble(vals[6]) + " Tm [" + ch
  +                          + "]");
  +            }
  +            
  +            gen.writeln("ET");
  +        } catch (IOException ioe) {
  +            handleIOException(ioe);
           }
  -
  -        psRenderer.write("ET");
       }
   
       /**
  @@ -863,83 +887,90 @@
        * @see #setClip
        */
       public void fill(Shape s) {
  -        // System.err.println("fill");
  -        psRenderer.write("gsave");
  -        Shape imclip = getClip();
  -        writeClip(imclip);
  -        Color c = getColor();
  -        psRenderer.write(c.getRed() + " " + c.getGreen() + " " + c.getBlue()
  -                         + " setrgbcolor");
  -
  -        applyPaint(getPaint(), true);
  -
  -        psRenderer.write("newpath");
  -        PathIterator iter = s.getPathIterator(getTransform());
  -        while (!iter.isDone()) {
  -            double vals[] = new double[6];
  -            int type = iter.currentSegment(vals);
  -            switch (type) {
  -            case PathIterator.SEG_CUBICTO:
  -                psRenderer.write(PDFNumber.doubleOut(1000 * vals[0]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[1]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[2]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[3]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[4]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[5])
  -                                 + " curveto");
  -                break;
  -            case PathIterator.SEG_LINETO:
  -                psRenderer.write(PDFNumber.doubleOut(1000 * vals[0]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[1])
  -                                 + " lineto");
  -                break;
  -            case PathIterator.SEG_MOVETO:
  -                psRenderer.write(PDFNumber.doubleOut(1000 * vals[0]) + " "
  -                                 + PDFNumber.doubleOut(1000 * vals[1])
  -                                 + " M");
  -                break;
  -            case PathIterator.SEG_QUADTO:
  -                // psRenderer.write(1000 * PDFNumber.doubleOut(vals[0]) +
  -                // " " + 1000 * PDFNumber.doubleOut(vals[1]) + " " +
  -                // 1000 * PDFNumber.doubleOut(vals[2]) + " " +
  -                // 1000 * PDFNumber.doubleOut(vals[3]) + " y\n");
  -                break;
  -            case PathIterator.SEG_CLOSE:
  -                psRenderer.write("closepath");
  -                break;
  -            default:
  -                break;
  +        try {
  +            // System.err.println("fill");
  +            gen.writeln("gsave");
  +            Shape imclip = getClip();
  +            writeClip(imclip);
  +            Color c = getColor();
  +            gen.writeln(c.getRed() + " " + c.getGreen() + " " + c.getBlue()
  +                             + " setrgbcolor");
  +            
  +            applyPaint(getPaint(), true);
  +            
  +            gen.writeln("newpath");
  +            PathIterator iter = s.getPathIterator(getTransform());
  +            while (!iter.isDone()) {
  +                double vals[] = new double[6];
  +                int type = iter.currentSegment(vals);
  +                switch (type) {
  +                case PathIterator.SEG_CUBICTO:
  +                    gen.writeln(gen.formatDouble(1000 * vals[0]) + " "
  +                              + gen.formatDouble(1000 * vals[1]) + " "
  +                              + gen.formatDouble(1000 * vals[2]) + " "
  +                              + gen.formatDouble(1000 * vals[3]) + " "
  +                              + gen.formatDouble(1000 * vals[4]) + " "
  +                              + gen.formatDouble(1000 * vals[5])
  +                              + " curveto");
  +                    break;
  +                case PathIterator.SEG_LINETO:
  +                    gen.writeln(gen.formatDouble(1000 * vals[0]) + " "
  +                              + gen.formatDouble(1000 * vals[1])
  +                              + " lineto");
  +                    break;
  +                case PathIterator.SEG_MOVETO:
  +                    gen.writeln(gen.formatDouble(1000 * vals[0]) + " "
  +                              + gen.formatDouble(1000 * vals[1])
  +                              + " M");
  +                    break;
  +                case PathIterator.SEG_QUADTO:
  +                    // psRenderer.write(1000 * PDFNumber.doubleOut(vals[0]) +
  +                    // " " + 1000 * PDFNumber.doubleOut(vals[1]) + " " +
  +                    // 1000 * PDFNumber.doubleOut(vals[2]) + " " +
  +                    // 1000 * PDFNumber.doubleOut(vals[3]) + " y\n");
  +                    break;
  +                case PathIterator.SEG_CLOSE:
  +                    gen.writeln("closepath");
  +                    break;
  +                default:
  +                    break;
  +                }
  +                iter.next();
               }
  -            iter.next();
  +            doDrawing(true, false,
  +                      iter.getWindingRule() == PathIterator.WIND_EVEN_ODD);
  +            gen.writeln("grestore");
  +        } catch (IOException ioe) {
  +            handleIOException(ioe);
           }
  -        doDrawing(true, false,
  -                  iter.getWindingRule() == PathIterator.WIND_EVEN_ODD);
  -        psRenderer.write("grestore");
       }
   
       /**
        * Commits a painting operation.
        * @param fill filling
        * @param stroke stroking
  +     * @param nonzero ???
  +     * @exception IOException In case of an I/O problem
        */
  -    protected void doDrawing(boolean fill, boolean stroke, boolean nonzero) {
  +    protected void doDrawing(boolean fill, boolean stroke, boolean nonzero) 
  +                throws IOException {
           if (fill) {
               if (stroke) {
                   if (!nonzero) {
  -                    psRenderer.write("stroke");
  +                    gen.writeln("stroke");
                   } else {
  -                    psRenderer.write("stroke");
  +                    gen.writeln("stroke");
                   }
               } else {
                   if (!nonzero) {
  -                    psRenderer.write("fill");
  +                    gen.writeln("fill");
                   } else {
  -                    psRenderer.write("fill");
  +                    gen.writeln("fill");
                   }
               }
           } else {
               // if(stroke)
  -            psRenderer.write("stroke");
  +            gen.writeln("stroke");
           }
       }
   
  
  
  
  1.28      +413 -148  xml-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.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- PSRenderer.java   8 Jan 2003 14:03:35 -0000       1.27
  +++ PSRenderer.java   27 Jan 2003 09:17:04 -0000      1.28
  @@ -8,16 +8,28 @@
   package org.apache.fop.render.ps;
   
   // Java
  +import java.awt.geom.Rectangle2D;
   import java.io.IOException;
   import java.io.OutputStream;
   import java.util.Iterator;
  +import java.util.List;
   import java.util.Map;
   
   // FOP
  +import org.apache.fop.apps.FOPException;
  +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.inline.ForeignObject;
  +import org.apache.fop.area.inline.Word;
   import org.apache.fop.datatypes.ColorType;
   import org.apache.fop.fonts.Font;
   import org.apache.fop.layout.FontInfo;
   import org.apache.fop.render.AbstractRenderer;
  +import org.apache.fop.render.RendererContext;
  +import org.w3c.dom.Document;
   
   
   /**
  @@ -32,21 +44,27 @@
    * sure to also follow the DSC to make it simpler to programmatically modify
    * the generated Postscript files (ex. extract pages etc.).
    * <br>
  + * The PS renderer operates in millipoints as the layout engine. Since PostScript
  + * initially uses points, scaling is applied as needed.
    * @todo Rebuild the PostScript renderer
  + * 
  + * @author <a href="mailto:[EMAIL PROTECTED]";>Apache XML FOP Development 
Team</a>
  + * @author <a href="mailto:[EMAIL PROTECTED]";>Jeremias Maerki</a>
  + * @version $Id$
    */
   public class PSRenderer extends AbstractRenderer {
   
  -    /**
  -     * the application producing the PostScript
  -     */
  +    /** The MIME type for PostScript */
  +    public static final String MIME_TYPE = "application/postscript";
  +
  +    /** The application producing the PostScript */
       protected String producer;
  +    private int currentPageNumber = 0;
   
       private boolean enableComments = true;
   
  -    /**
  -     * the stream used to output the PostScript
  -     */
  -    protected PSStream out;
  +    /** The PostScript generator used to output the PostScript */
  +    protected PSGenerator gen;
       private boolean ioTrouble = false;
   
       private String currentFontName;
  @@ -72,13 +90,17 @@
        * Write out a command
        * @param cmd PostScript command
        */
  -    protected void write(String cmd) {
  +    protected void writeln(String cmd) {
           try {
  -            out.write(cmd);
  -        } catch (IOException e) {
  -            if (!ioTrouble) {
  -                e.printStackTrace();
  -            }
  +            gen.writeln(cmd);
  +        } catch (IOException ioe) {
  +            handleIOTrouble(ioe);
  +        }
  +    }
  +
  +    protected void handleIOTrouble(IOException ioe) {
  +        if (!ioTrouble) {
  +            getLogger().error("Error while writing to target file", ioe);
               ioTrouble = true;
           }
       }
  @@ -89,7 +111,7 @@
        */
       protected void comment(String comment) {
           if (this.enableComments) {
  -            write(comment);
  +            writeln(comment);
           }
       }
   
  @@ -98,71 +120,9 @@
        * @param fontInfo available fonts
        */
       protected void writeFontDict(FontInfo fontInfo) {
  -        write("%%BeginResource: procset FOPFonts");
  -        write("%%Title: Font setup (shortcuts) for this file");
  -        write("/FOPFonts 100 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("/ux 0.0 def");
  -        write("/uy 0.0 def");
  -        // write("/cf /Helvetica def");
  -        // write("/cs 12000 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");
  -
  -
  +        writeln("%%BeginResource: procset FOPFonts");
  +        writeln("%%Title: Font setup (shortcuts) for this file");
  +        writeln("/FOPFonts 100 dict dup begin");
   
           // write("/gfF1{/Helvetica findfont} bd");
           // write("/gfF3{/Helvetica-Bold findfont} bd");
  @@ -171,21 +131,21 @@
           while (enum.hasNext()) {
               String key = (String)enum.next();
               Font fm = (Font)fonts.get(key);
  -            write("/" + key + " /" + fm.getFontName() + " def");
  +            writeln("/" + key + " /" + fm.getFontName() + " def");
           }
  -        write("end def");
  -        write("%%EndResource");
  +        writeln("end def");
  +        writeln("%%EndResource");
           enum = fonts.keySet().iterator();
           while (enum.hasNext()) {
               String key = (String)enum.next();
               Font fm = (Font)fonts.get(key);
  -            write("/" + fm.getFontName() + " 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.getFontName() + " exch definefont pop");
  +            writeln("/" + fm.getFontName() + " findfont");
  +            writeln("dup length dict begin");
  +            writeln("  {1 index /FID ne {def} {pop pop} ifelse} forall");
  +            writeln("  /Encoding ISOLatin1Encoding def");
  +            writeln("  currentdict");
  +            writeln("end");
  +            writeln("/" + fm.getFontName() + " exch definefont pop");
           }
       }
   
  @@ -193,10 +153,39 @@
        * Make sure the cursor is in the right place.
        */
       protected void movetoCurrPosition() {
  -        write(this.currentIPPosition + " " + this.currentBPPosition + " M");
  +        moveTo(this.currentIPPosition, this.currentBPPosition);
       }
   
       /**
  +     * Moves the cursor.
  +     * @param x X coordinate
  +     * @param y Y coordinate
  +     */
  +    protected void moveTo(int x, int y) {
  +        writeln(x + " " + y + " M");
  +    }
  +
  +    /** Saves the graphics state of the rendering engine. */
  +    protected void saveGraphicsState() {
  +        writeln("gsave");
  +    }
  +    
  +    /** Restores the last graphics state of the rendering engine. */
  +    protected void restoreGraphicsState() {
  +        writeln("grestore");
  +    }
  +    
  +    /** Indicates the beginning of a text object. */
  +    protected void beginTextObject() {
  +        writeln("BT");
  +    }
  +        
  +    /** Indicates the end of a text object. */
  +    protected void endTextObject() {
  +        writeln("ET");
  +    }
  +        
  +    /**
        * Set up the font info
        *
        * @param fontInfo the font info object to set up
  @@ -215,17 +204,27 @@
        * @param h height
        * @param col color to fill with
        */
  -    protected void addFilledRect(int x, int y, int w, int h,
  +    protected void fillRect(int x, int y, int w, int h,
                                    ColorType col) {
  -        write("newpath");
  -        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");
  +        writeln(x + " " + y + " " + w + " " + h + " rectfill");
  +    }
  +
  +    protected void drawRect(int x, int y, int w, int h) {
  +        writeln(x + " " + y + " " + w + " " + h + " rectstroke");
  +    }
  +
  +    /**
  +     * Clip an area.
  +     * Write a clipping operation given coordinates in the current
  +     * transform.
  +     * @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 clip(float x, float y, float width, float height) {
  +        writeln(x + " " + y + " " + width + " " + height + " rectclip");
       }
   
       /**
  @@ -235,7 +234,7 @@
        */
       public void useFont(String name, int size) {
           if ((currentFontName != name) || (currentFontSize != size)) {
  -            write(name + " " + size + " F");
  +            writeln(name + " " + size + " F");
               currentFontName = name;
               currentFontSize = size;
           }
  @@ -247,7 +246,7 @@
   
       private void useColor(float red, float green, float blue) {
           if ((red != currRed) || (green != currGreen) || (blue != currBlue)) {
  -            write(red + " " + green + " " + blue + " setrgbcolor");
  +            writeln(red + " " + green + " " + blue + " setrgbcolor");
               currRed = red;
               currGreen = green;
               currBlue = blue;
  @@ -258,61 +257,327 @@
        * @see org.apache.fop.render.Renderer#startRenderer(OutputStream)
        */
       public void startRenderer(OutputStream outputStream)
  -    throws IOException {
  +                throws IOException {
           getLogger().debug("rendering areas to PostScript");
   
  -        this.out = new PSStream(outputStream);
  -        write("%!PS-Adobe-3.0");
  -        write("%%Creator: " + this.producer);
  -        write("%%DocumentProcessColors: Black");
  -        write("%%DocumentSuppliedResources: procset FOPFonts");
  -        write("%%EndComments");
  -        write("%%BeginDefaults");
  -        write("%%EndDefaults");
  -        write("%%BeginProlog");
  -        write("%%EndProlog");
  -        write("%%BeginSetup");
  +        //Setup for PostScript generation
  +        this.gen = new PSGenerator(outputStream);
  +        this.currentPageNumber = 0;
  +        
  +        //PostScript Header
  +        writeln(DSCConstants.PS_ADOBE_30);
  +        gen.writeDSCComment(DSCConstants.CREATOR, new String[] {"FOP " + 
this.producer});
  +        gen.writeDSCComment(DSCConstants.CREATION_DATE, new Object[] {new 
java.util.Date()});
  +        gen.writeDSCComment(DSCConstants.PAGES, new Object[] {PSGenerator.ATEND});
  +        gen.writeDSCComment(DSCConstants.END_COMMENTS);
  +        
  +        //Defaults
  +        gen.writeDSCComment(DSCConstants.BEGIN_DEFAULTS);
  +        gen.writeDSCComment(DSCConstants.END_DEFAULTS);
  +        
  +        //Prolog
  +        gen.writeDSCComment(DSCConstants.BEGIN_PROLOG);
  +        gen.writeDSCComment(DSCConstants.END_PROLOG);
  +        
  +        //Setup
  +        gen.writeDSCComment(DSCConstants.BEGIN_SETUP);
  +        PSProcSets.writeFOPStdProcSet(gen);
  +        PSProcSets.writeFOPEPSProcSet(gen);
           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");
  -        write("FOPFonts begin");
  +        gen.writeDSCComment(DSCConstants.END_SETUP);
       }
   
       /**
        * @see org.apache.fop.render.Renderer#stopRenderer()
        */
       public void stopRenderer() throws IOException {
  -        write("%%Trailer");
  -        write("%%EOF");
  -        this.out.flush();
  +        gen.writeDSCComment(DSCConstants.TRAILER);
  +        gen.writeDSCComment(DSCConstants.PAGES, new 
Integer(this.currentPageNumber));
  +        gen.writeDSCComment(DSCConstants.EOF);
  +        gen.flush();
  +    }
  +
  +    /**
  +     * @see org.apache.fop.render.Renderer#renderPage(PageViewport)
  +     */
  +    public void renderPage(PageViewport page)
  +            throws IOException, FOPException {
  +        getLogger().debug("renderPage(): " + page);
  +        
  +        this.currentPageNumber++;
  +        gen.writeDSCComment(DSCConstants.PAGE, new Object[] 
  +                {page.getPageNumber(),
  +                 new Integer(this.currentPageNumber)});
  +        final Integer zero = new Integer(0);
  +        final Long pagewidth = new Long(Math.round(page.getViewArea().getWidth() / 
1000f));
  +        final Long pageheight = new Long(Math.round(page.getViewArea().getHeight() 
/ 1000f));
  +        gen.writeDSCComment(DSCConstants.PAGE_BBOX, new Object[]
  +                {zero, zero, pagewidth, pageheight});
  +        gen.writeDSCComment(DSCConstants.BEGIN_PAGE_SETUP);         
  +        gen.writeln("FOPFonts begin");
  +        gen.writeln("[1 0 0 -1 0 " + pageheight + "] concat");
  +        gen.writeln("0.001 0.001 scale");
  +        gen.writeDSCComment(DSCConstants.END_PAGE_SETUP);         
  +        
  +        //Process page
  +        super.renderPage(page);
  +        
  +        writeln("showpage");        
  +        gen.writeDSCComment(DSCConstants.PAGE_TRAILER);
  +        gen.writeDSCComment(DSCConstants.END_PAGE);
  +    }
  +
  +    protected void paintText(int rx, int bl, String text, Font font) {
  +        saveGraphicsState();
  +        writeln("1 0 0 -1 " + rx + " " + bl + " Tm");
  +        
  +        int initialSize = text.length();
  +        initialSize += initialSize / 2;
  +        StringBuffer sb = new StringBuffer(initialSize);
  +        sb.append("(");
  +        for (int i = 0; i < text.length(); i++) {
  +            final char c = text.charAt(i);
  +            final char mapped = font.mapChar(c);
  +            gen.escapeChar(mapped, sb);
  +        }
  +        sb.append(") t");
  +        writeln(sb.toString());
  +        restoreGraphicsState();
  +    }
  +
  +    /**
  +     * @see org.apache.fop.render.Renderer#renderWord(Word)
  +     */
  +    public void renderWord(Word area) {
  +        String fontname = (String)area.getTrait(Trait.FONT_NAME);
  +        int fontsize = area.getTraitAsInteger(Trait.FONT_SIZE);
  +
  +        // This assumes that *all* CIDFonts use a /ToUnicode mapping
  +        Font f = (Font)fontInfo.getFonts().get(fontname);
  +        
  +        //Determine position
  +        int rx = currentBlockIPPosition;
  +        int bl = currentBPPosition + area.getOffset();
  +
  +        useFont(fontname, fontsize);
  +        
  +        paintText(rx, bl, area.getWord(), f);
  +
  +/*
  +        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.toString()).append(") A")).toString();
  +        } else {
  +            psString = (new StringBuffer("(").append(sb.toString())
  +              .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();
  +        */
  +        super.renderWord(area); //Updates IPD
       }
  +
  +
  +    /**
  +     * @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();
  +
  +        if (bv.getPositioning() == Block.ABSOLUTE) {
  +
  +            currentIPPosition = 0;
  +            currentBPPosition = 0;
  +
  +            //closeText();
  +            endTextObject();
  +
  +            if (bv.getClip()) {
  +                saveGraphicsState();
  +                int x = bv.getXOffset() + containingIPPosition;
  +                int y = bv.getYOffset() + containingBPPosition;
  +                int width = bv.getWidth();
  +                int height = bv.getHeight();
  +                clip(x, y, width, height);
  +            }
  +
  +            CTM tempctm = new CTM(containingIPPosition, containingBPPosition);
  +            ctm = tempctm.multiply(ctm);
  +
  +            startVParea(ctm);
  +            handleBlockTraits(bv);
  +            renderBlocks(children);
  +            endVParea();
  +
  +            if (bv.getClip()) {
  +                restoreGraphicsState();
  +            }
  +            beginTextObject();
  +
  +            // clip if necessary
  +
  +            currentIPPosition = saveIP;
  +            currentBPPosition = saveBP;
  +        } else {
  +
  +            if (ctm != null) {
  +                currentIPPosition = 0;
  +                currentBPPosition = 0;
  +
  +                //closeText();
  +                endTextObject();
  +
  +                double[] vals = ctm.toArray();
  +                //boolean aclock = vals[2] == 1.0;
  +                if (vals[2] == 1.0) {
  +                    ctm = ctm.translate(-saveBP - bv.getHeight(), -saveIP);
  +                } else if (vals[0] == -1.0) {
  +                    ctm = ctm.translate(-saveIP - bv.getWidth(), -saveBP - 
bv.getHeight());
  +                } else {
  +                    ctm = ctm.translate(saveBP, saveIP - bv.getWidth());
  +                }
  +            }
  +
  +            // clip if necessary
  +            if (bv.getClip()) {
  +                if (ctm == null) {
  +                    //closeText();
  +                    endTextObject();
  +                }
  +                saveGraphicsState();
  +                int x = bv.getXOffset();
  +                int y = bv.getYOffset();
  +                int width = bv.getWidth();
  +                int height = bv.getHeight();
  +                clip(x, y, width, height);
  +            }
  +
  +            if (ctm != null) {
  +                startVParea(ctm);
  +            }
  +            handleBlockTraits(bv);
  +            renderBlocks(children);
  +            if (ctm != null) {
  +                endVParea();
  +            }
  +
  +            if (bv.getClip()) {
  +                restoreGraphicsState();
  +                if (ctm == null) {
  +                    beginTextObject();
  +                }
  +            }
  +            if (ctm != null) {
  +                beginTextObject();
  +            }
  +
  +            currentIPPosition = saveIP;
  +            currentBPPosition = saveBP;
  +            currentBPPosition += (int)(bv.getHeight());
  +        }
  +        currentFontName = saveFontName;
  +    }
  +    
  +    /**
  +     * @see org.apache.fop.render.AbstractRenderer#startVParea(CTM)
  +     */
  +    protected void startVParea(CTM ctm) {
  +        // Set the given CTM in the graphics state
  +        //currentState.push();
  +        //currentState.setTransform(new AffineTransform(CTMHelper.toPDFArray(ctm)));
  +
  +        saveGraphicsState();
  +        // multiply with current CTM
  +        //currentStream.add(CTMHelper.toPDFString(ctm) + " cm\n");
  +        final double matrix[] = ctm.toArray();
  +        writeln("[" + gen.formatDouble(matrix[0]) 
  +                + " " + gen.formatDouble(matrix[1])
  +                + " " + gen.formatDouble(matrix[2]) 
  +                + " " + gen.formatDouble(matrix[3])
  +                + " " + gen.formatDouble(matrix[4])
  +                + " " + gen.formatDouble(matrix[5]) + "] concat");
  +        
  +        // Set clip?
  +        beginTextObject();        
  +    }
  +
  +    /**
  +     * @see org.apache.fop.render.AbstractRenderer#endVParea()
  +     */
  +    protected void endVParea() {
  +        endTextObject();
  +        restoreGraphicsState();
  +        //currentState.pop();
  +    }
  +
  +    
  +    /**
  +     * @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);
  +    }
  +
  +    public void renderDocument(Document doc, String ns, Rectangle2D pos) {
  +        RendererContext context;
  +        context = new RendererContext(MIME_TYPE);
  +        context.setUserAgent(userAgent);
  +
  +        /*
  +        context.setProperty(PDFXMLHandler.PDF_DOCUMENT, pdfDoc);
  +        context.setProperty(PDFXMLHandler.OUTPUT_STREAM, ostream);
  +        context.setProperty(PDFXMLHandler.PDF_STATE, currentState);
  +        context.setProperty(PDFXMLHandler.PDF_PAGE, currentPage);
  +        context.setProperty(PDFXMLHandler.PDF_CONTEXT, 
  +                    currentContext == null ? currentPage: currentContext);
  +        context.setProperty(PDFXMLHandler.PDF_CONTEXT, currentContext);
  +        context.setProperty(PDFXMLHandler.PDF_STREAM, currentStream);
  +        context.setProperty(PDFXMLHandler.PDF_XPOS,
  +                            new Integer(currentBlockIPPosition + (int) pos.getX()));
  +        context.setProperty(PDFXMLHandler.PDF_YPOS,
  +                            new Integer(currentBPPosition + (int) pos.getY()));
  +        context.setProperty(PDFXMLHandler.PDF_FONT_INFO, fontInfo);
  +        context.setProperty(PDFXMLHandler.PDF_FONT_NAME, currentFontName);
  +        context.setProperty(PDFXMLHandler.PDF_FONT_SIZE,
  +                            new Integer(currentFontSize));
  +        context.setProperty(PDFXMLHandler.PDF_WIDTH,
  +                            new Integer((int) pos.getWidth()));
  +        context.setProperty(PDFXMLHandler.PDF_HEIGHT,
  +                            new Integer((int) pos.getHeight()));
  +        */           
  +        userAgent.renderXML(context, doc, ns);
  +
  +    }
  +
  +    
  +
   
   }
  
  
  
  1.1                  xml-fop/src/org/apache/fop/render/ps/DSCConstants.java
  
  Index: DSCConstants.java
  ===================================================================
  /*
   * $Id: DSCConstants.java,v 1.1 2003/01/27 09:17:04 jeremias Exp $
   * Copyright (C) 2003 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;
  
  /**
   * This class defines constants with Strings for the DSC specification.
   * 
   * @author <a href="mailto:[EMAIL PROTECTED]";>Apache XML FOP Development 
Team</a>
   * @author <a href="mailto:[EMAIL PROTECTED]";>Jeremias Maerki</a>
   * @version $Id: DSCConstants.java,v 1.1 2003/01/27 09:17:04 jeremias Exp $
   */
  public class DSCConstants {
  
      // ----==== General Header Comments ====----
      
      /** Lead-in for a DSC-conformant PostScript file */
      public static final String PS_ADOBE_30       = "%!PS-Adobe-3.0";
      
      /** Bounding box for the document */
      public static final String BBOX              = "BoundingBox";
      /** Copyright information associated with the document or resource */
      public static final String COPYRIGHT         = "Copyright";
      /** Creator of the document */
      public static final String CREATOR           = "Creator";
      /** Date and time when the document was created */
      public static final String CREATION_DATE     = "CreationDate";
      /** Type of data */
      public static final String DOCUMENT_DATA     = "BoundingBox";
      /** Use for inidicating an emulator being invoked in the document */
      public static final String EMULATION         = "Emulation";
      /** Explicit end of comments */
      public static final String END_COMMENTS      = "EndComments";
      /** Required PostScript Level 1 extension for this document */
      public static final String EXTENSIONS        = "Extensions";
      /** Indicates who is this document printed for */
      public static final String FOR               = "For";
      /** Indicates the PostScript language level used in the document */
      public static final String LANGUAGE_LEVEL    = "LanguageLevel";
      /** Indicates the orientation of the document */
      public static final String ORIENTATION       = "Orientation";
      /** Number of pages in the document */
      public static final String PAGES             = "Pages";
      /** Indicates the order of the pages */
      public static final String PAGE_ORDER        = "PageOrder";
      /** Indicates how the document should be routed back to its owner */
      public static final String ROUTING           = "Routing";
      /** Title of the document */
      public static final String TITLE             = "Title";
      /** Version of the document */
      public static final String VERSION           = "Version";
   
      // ----==== General Body Comments ====----
      
      /** Indicates a continued line */
      public static final String NEXT_LINE         = "+ ";
      
      //Skipping BeginBinary/EndBinary. They are deprecated.
      
      /** Indicates the start of a data section*/
      public static final String BEGIN_DATA        = "BeginData";
      /** Indicates the end of a data section*/
      public static final String END_DATA          = "EndData";
      
      /** Indicates the start of the defaults section */
      public static final String BEGIN_DEFAULTS    = "BeginDefaults";
      /** Indicates the end of the defaults section */
      public static final String END_DEFAULTS      = "EndDefaults";
      
      /** Indicates the start of a non-PostScript section */
      public static final String BEGIN_EMULATION   = "BeginEmulation";
      /** Indicates the end of a non-PostScript section */
      public static final String END_EMULATION     = "EndEmulation";
      
      /** Indicates the start of a preview section (EPS only)*/
      public static final String BEGIN_PREVIEW     = "BeginPreview";
      /** Indicates the end of a preview section (EPS only)*/
      public static final String END_PREVIEW       = "EndPreview";
      
      /** Indicates the start of the prolog */
      public static final String BEGIN_PROLOG      = "BeginProlog";
      /** Indicates the end of the prolog */
      public static final String END_PROLOG        = "EndProlog";
      
      /** Indicates the start of the document setup */
      public static final String BEGIN_SETUP       = "BeginSetup";
      /** Indicates the end of the document setup */
      public static final String END_SETUP         = "EndSetup";
  
  
      // ----==== General Page Comments ====----
      
      /** Indicates the start of a graphic object */
      public static final String BEGIN_OBJECT      = "BeginObject";
      /** Indicates the end of a graphic object */
      public static final String END_OBJECT        = "EndObject";
  
      /** Indicates the start of the page setup section */
      public static final String BEGIN_PAGE_SETUP  = "BeginPageSetup";
      /** Indicates the end of the page setup section */
      public static final String END_PAGE_SETUP    = "EndPageSetup";
  
      /** Indicates a page number */
      public static final String PAGE              = "Page";
      /** Bounding box for a page */
      public static final String PAGE_BBOX         = "PageBoundingBox";
      /** Bounding box for a page */
      public static final String PAGE_ORIENTATION  = "PageOrientation";
  
      
      // ----==== General Trailer Comments ====----
  
      /** Indicates the start of the page trailer */    
      public static final String PAGE_TRAILER     = "PageTrailer";
      /** Indicates the start of the document trailer */    
      public static final String TRAILER          = "Trailer";
      /** Indicates the end of a page (NON-STANDARD!) */    
      public static final String END_PAGE         = "EndPage";
      /** Indicates the end of the document */    
      public static final String EOF              = "EOF";
  
  
      // ----==== Requirements Conventions ====----
  
      /**@todo Add the missing comments */
      
      // ----==== Requirement Body Comments ====----
      
      /** Indicates the start of an embedded document */
      public static final String BEGIN_DOCUMENT   = "BeginDocument";
      /** Indicates the end of an embedded document */
      public static final String END_DOCUMENT     = "EndDocument";
      /** Indicates a referenced embedded document */
      public static final String INCLUDE_DOCUMENT = "IncludeDocument";
      
      /** Indicates the start of a PPD feature */
      public static final String BEGIN_FEATURE    = "BeginFeature";
      /** Indicates the end of a PPD feature */
      public static final String END_FEATURE      = "EndFeature";
      /** Indicates a referenced a PPD feature */
      public static final String INCLUDE_FEATURE  = "IncludeFeature";
      
      //Skipping BeginFile/EndFile/IncludeFile. They are deprecated.
      //Skipping BeginFont/EndFont/IncludeFont. They are deprecated.
      //Skipping BeginProcSet/EndProcSet/IncludeProcSet. They are deprecated.
      
      /** Indicates the start of a resource (font, file, procset) */
      public static final String BEGIN_RESOURCE       = "BeginResource";
      /** Indicates the end of a resource (font, file, procset) */
      public static final String END_RESOURCE         = "EndResource";
      /** Indicates a referenced a resource (font, file, procset) */
      public static final String INCLUDE_RESOURCE     = "IncludeResource";
      
      
  }
  
  
  
  1.1                  xml-fop/src/org/apache/fop/render/ps/PSGenerator.java
  
  Index: PSGenerator.java
  ===================================================================
  /*
   * $Id: PSGenerator.java,v 1.1 2003/01/27 09:17:04 jeremias Exp $
   * 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;
  
  import java.io.OutputStream;
  import java.io.IOException;
  import java.text.DateFormat;
  import java.text.NumberFormat;
  import java.util.Date;
  
  /**
   * This class is used to output PostScript code to an OutputStream.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Apache XML FOP Development 
Team</a>
   * @author <a href="mailto:[EMAIL PROTECTED]";>Jeremias Maerki</a>
   * @version $Id: PSGenerator.java,v 1.1 2003/01/27 09:17:04 jeremias Exp $
   */
  public class PSGenerator {
  
      /** 
       * Indicator for the PostScript interpreter that the value is provided 
       * later in the document (mostly in the %%Trailer section).
       */
      public static final AtendIndicator ATEND = new AtendIndicator() {};
  
      private OutputStream out;
  
      private StringBuffer tempBuffer = new StringBuffer(256);
  
      /** @see java.io.FilterOutputStream **/
      public PSGenerator(OutputStream out) {
          this.out = out;
      }
  
      /**
       * Writes a newline character to the OutputStream.
       * 
       * @throws IOException In case of an I/O problem
       */
      public final void newLine() throws IOException {
          out.write('\n');
      }
  
      /**
       * Formats a double value for PostScript output.
       * 
       * @param value value to format
       * @return the formatted value
       */
      public String formatDouble(double value) {
          NumberFormat nf = new java.text.DecimalFormat("0.#");
          return nf.format(value);
      }
  
      /**
       * Writes a PostScript command to the stream.
       *
       * @param cmd              The PostScript code to be written.
       * @exception IOException  In case of an I/O problem
       */
      public void write(String cmd) throws IOException {
          if (cmd.length() > 255) {
              throw new RuntimeException("PostScript command exceeded limit of 255 
characters");
          }
          out.write(cmd.getBytes("US-ASCII"));
      }
  
      /**
       * Writes a PostScript command to the stream and ends the line.
       *
       * @param cmd              The PostScript code to be written.
       * @exception IOException  In case of an I/O problem
       */
      public void writeln(String cmd) throws IOException {
          write(cmd);
          newLine();
      }
  
      /**
       * Writes encoded data to the PostScript stream.
       *
       * @param cmd              The encoded PostScript code to be written.
       * @exception IOException  In case of an I/O problem
       */
      public void writeByteArr(byte[] cmd) throws IOException {
          out.write(cmd);
          newLine();
      }
      
      
      /**
       * Flushes the OutputStream.
       * 
       * @exception IOException In case of an I/O problem
       */
      public void flush() throws IOException {
          out.flush();
      }
  
  
      /**
       * Escapes a character conforming to the rules established in the PostScript
       * Language Reference (Search for "Literal Text Strings").
       * @param c character to escape
       * @param target target StringBuffer to write the escaped character to
       */
      public static final void escapeChar(char c, StringBuffer target) {
          if (c > 127) {
              target.append("\\");
              target.append(Integer.toOctalString(c));
          } else {
              switch (c) {
                  case '\n':
                      target.append("\\n");
                      break;
                  case '\r':
                      target.append("\\r");
                      break;
                  case '\t':
                      target.append("\\t");
                      break;
                  case '\b':
                      target.append("\\b");
                      break;
                  case '\f':
                      target.append("\\f");
                      break;
                  case '\\':
                      target.append("\\\\");
                      break;
                  case '(':
                      target.append("\\(");
                      break;
                  case ')':
                      target.append("\\)");
                      break;
                  default:
                      target.append(c);
              }
          }
      }
  
  
      /**
       * Converts text by applying escaping rules established in the DSC specs.
       * @param text Text to convert
       * @return String The resulting String
       */
      public static final String convertStringToDSC(String text) {
          return convertStringToDSC(text, false);
      }
  
  
      /**
       * Converts text by applying escaping rules established in the DSC specs.
       * @param text Text to convert
       * @param forceParentheses Force the use of parentheses
       * @return String The resulting String
       */
      public static final String convertStringToDSC(String text, 
                                                    boolean forceParentheses) {
          if ((text == null) || (text.length() == 0)) {
              return "()";
          } else {
              int initialSize = text.length();
              initialSize += initialSize / 2;
              StringBuffer sb = new StringBuffer(initialSize);
              if ((Long.getLong(text) != null) 
                      || (text.indexOf(" ") >= 0) 
                      || forceParentheses) {
                          
                  sb.append("(");
                  for (int i = 0; i < text.length(); i++) {
                      final char c = text.charAt(i);
                      escapeChar(c, sb);
                  }
                  sb.append(")");
                  return sb.toString();
              } else {
                  return text;
              }
          }
      }
  
  
      /**
       * Writes a DSC comment to the output stream.
       * @param name Name of the DSC comment
       * @exception IOException In case of an I/O problem
       * @see org.apache.fop.render.ps.DSCConstants
       */
      public void writeDSCComment(String name) throws IOException {
          writeln("%%" + name);
      }
  
  
      /**
       * Writes a DSC comment to the output stream. The parameter to the DSC 
       * comment can be any object. The object is converted to a String as
       * necessary.
       * @param name Name of the DSC comment
       * @param param Single parameter to the DSC comment
       * @exception IOException In case of an I/O problem
       * @see org.apache.fop.render.ps.DSCConstants
       */
      public void writeDSCComment(String name, Object param) throws IOException {
          writeDSCComment(name, new Object[] {param});    
      }
  
          
      /**
       * Writes a DSC comment to the output stream. The parameters to the DSC 
       * comment can be any object. The objects are converted to Strings as
       * necessary. Please see the source code to find out what parameters are
       * currently supported.
       * @param name Name of the DSC comment
       * @param params Array of parameters to the DSC comment
       * @exception IOException In case of an I/O problem
       * @see org.apache.fop.render.ps.DSCConstants
       */
      public void writeDSCComment(String name, Object[] params) throws IOException {
          tempBuffer.setLength(0);
          tempBuffer.append("%%");
          tempBuffer.append(name);
          if ((params != null) && (params.length > 0)) {
              tempBuffer.append(": ");
              for (int i = 0; i < params.length; i++) {
                  if (i > 0) {
                      tempBuffer.append(" ");
                  }
                  
                  if (params[i] instanceof String) {
                      tempBuffer.append(convertStringToDSC((String)params[i]));
                  } else if (params[i] instanceof AtendIndicator) {
                      tempBuffer.append("(atend)");
                  } else if (params[i] instanceof Number) {
                      tempBuffer.append(params[i].toString());
                  } else if (params[i] instanceof Date) {
                      DateFormat df = new 
java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
                      
tempBuffer.append(convertStringToDSC(df.format((Date)params[i])));
                  } else {
                      throw new IllegalArgumentException("Unsupported parameter type: 
" 
                              + params[i].getClass().getName());
                  }
              }
          }
          writeln(tempBuffer.toString());
      }
      
      
      /** Used for the ATEND constant. See there. */
      private static interface AtendIndicator {
      }
  
  }
  
  
  
  1.1                  xml-fop/src/org/apache/fop/render/ps/PSProcSets.java
  
  Index: PSProcSets.java
  ===================================================================
  /*
   * $Id: PSProcSets.java,v 1.1 2003/01/27 09:17:04 jeremias Exp $
   * Copyright (C) 2001-2003 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;
  
  import java.io.IOException;
  
  /**
   * This class defines the basic resources (procsets) used by FOP's PostScript
   * renderer and SVG transcoder.
   * 
   * @author <a href="mailto:[EMAIL PROTECTED]";>Apache XML FOP Development 
Team</a>
   * @author <a href="mailto:[EMAIL PROTECTED]";>Jeremias Maerki</a>
   * @version $Id: PSProcSets.java,v 1.1 2003/01/27 09:17:04 jeremias Exp $
   */
  public final class PSProcSets {
  
      /**
       * Generates a resource defining standard procset for FOP.
       * @param gen PSGenerator to use for output
       * @throws IOException In case of an I/O problem
       */
      public static final void writeFOPStdProcSet(PSGenerator gen) throws IOException {
          gen.writeln("%%BeginResource: procset (Apache FOP Std ProcSet) 1.0 0");
          gen.writeln("%%Version: 1.0 0");
          gen.writeln("%%Copyright: Copyright (C) 2001-2003 "
                      + "The Apache Software Foundation. All rights reserved.");
          gen.writeln("%%Title: Basic set of procedures used by FOP");
  
          gen.writeln("/bd{bind def}bind def");
          gen.writeln("/ld{load def}bd");
          gen.writeln("/M/moveto ld");
          gen.writeln("/RM/rmoveto ld");
          gen.writeln("/t/show ld");
  
          gen.writeln("/_ctm matrix def"); //Holds the current matrix
          gen.writeln("/_tm matrix def");
          //BT: save currentmatrix, set _tm to identitymatrix and move to 0/0
          gen.writeln("/BT { _ctm currentmatrix pop matrix _tm copy pop 0 0 moveto } 
bd"); 
          //ET: restore last currentmatrix
          gen.writeln("/ET { _ctm setmatrix } bd");
          gen.writeln("/iTm { _ctm setmatrix _tm concat } bd");
          gen.writeln("/Tm { _tm astore pop iTm 0 0 moveto } bd");
          
          gen.writeln("/ux 0.0 def");
          gen.writeln("/uy 0.0 def");
  
          // <font> <size> F
          gen.writeln("/F {");
          gen.writeln("  /Tp exch def");
          // gen.writeln("  currentdict exch get");
          gen.writeln("  /Tf exch def");
          gen.writeln("  Tf findfont Tp scalefont setfont");
          gen.writeln("  /cf Tf def  /cs Tp def  /cw ( ) stringwidth pop def");
          gen.writeln("} bd");
  
          gen.writeln("/ULS {currentpoint /uy exch def /ux exch def} bd");
          gen.writeln("/ULE {");
          gen.writeln("  /Tcx currentpoint pop def");
          gen.writeln("  gsave");
          gen.writeln("  newpath");
          gen.writeln("  cf findfont cs scalefont dup");
          gen.writeln("  /FontMatrix get 0 get /Ts exch def /FontInfo get dup");
          gen.writeln("  /UnderlinePosition get Ts mul /To exch def");
          gen.writeln("  /UnderlineThickness get Ts mul /Tt exch def");
          gen.writeln("  ux uy To add moveto  Tcx uy To add lineto");
          gen.writeln("  Tt setlinewidth stroke");
          gen.writeln("  grestore");
          gen.writeln("} bd");
  
          gen.writeln("/OLE {");
          gen.writeln("  /Tcx currentpoint pop def");
          gen.writeln("  gsave");
          gen.writeln("  newpath");
          gen.writeln("  cf findfont cs scalefont dup");
          gen.writeln("  /FontMatrix get 0 get /Ts exch def /FontInfo get dup");
          gen.writeln("  /UnderlinePosition get Ts mul /To exch def");
          gen.writeln("  /UnderlineThickness get Ts mul /Tt exch def");
          gen.writeln("  ux uy To add cs add moveto Tcx uy To add cs add lineto");
          gen.writeln("  Tt setlinewidth stroke");
          gen.writeln("  grestore");
          gen.writeln("} bd");
  
          gen.writeln("/SOE {");
          gen.writeln("  /Tcx currentpoint pop def");
          gen.writeln("  gsave");
          gen.writeln("  newpath");
          gen.writeln("  cf findfont cs scalefont dup");
          gen.writeln("  /FontMatrix get 0 get /Ts exch def /FontInfo get dup");
          gen.writeln("  /UnderlinePosition get Ts mul /To exch def");
          gen.writeln("  /UnderlineThickness get Ts mul /Tt exch def");
          gen.writeln("  ux uy To add cs 10 mul 26 idiv add moveto "
                      + "Tcx uy To add cs 10 mul 26 idiv add lineto");
          gen.writeln("  Tt setlinewidth stroke");
          gen.writeln("  grestore");
          gen.writeln("} bd");
  
          gen.writeln("%%EndResource");
      }
  
  
      /**
       * Generates a resource defining a procset for including EPS graphics.
       * @param gen PSGenerator to use for output
       * @throws IOException In case of an I/O problem
       */
      public static final void writeFOPEPSProcSet(PSGenerator gen) throws IOException {
          gen.writeln("%%BeginResource: procset (Apache FOP EPS ProcSet) 1.0 0");
          gen.writeln("%%Version: 1.0 0");
          gen.writeln("%%Copyright: Copyright (C) 2002-2003 "
                      + "The Apache Software Foundation. All rights reserved.");
          gen.writeln("%%Title: EPS procedures used by FOP");
  
          gen.writeln("/BeginEPSF { %def");
          gen.writeln("/b4_Inc_state save def         % Save state for cleanup");
          gen.writeln("/dict_count countdictstack def % Count objects on dict stack");
          gen.writeln("/op_count count 1 sub def      % Count objects on operand 
stack");
          gen.writeln("userdict begin                 % Push userdict on dict stack");
          gen.writeln("/showpage { } def              % Redefine showpage, { } = null 
proc");
          gen.writeln("0 setgray 0 setlinecap         % Prepare graphics state");
          gen.writeln("1 setlinewidth 0 setlinejoin");
          gen.writeln("10 setmiterlimit [ ] 0 setdash newpath");
          gen.writeln("/languagelevel where           % If level not equal to 1 then");
          gen.writeln("{pop languagelevel             % set strokeadjust and");
          gen.writeln("1 ne                           % overprint to their defaults.");
          gen.writeln("{false setstrokeadjust false setoverprint");
          gen.writeln("} if");
          gen.writeln("} if");
          gen.writeln("} bd");
  
          gen.writeln("/EndEPSF { %def");
          gen.writeln("count op_count sub {pop} repeat            % Clean up stacks");
          gen.writeln("countdictstack dict_count sub {end} repeat");
          gen.writeln("b4_Inc_state restore");
          gen.writeln("} bd");
          
          gen.writeln("%%EndResource");
      }
  
  }
  
  
  

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

Reply via email to