/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id$ */

package org.apache.fop.svg;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Paint;
import java.awt.PaintContext;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DirectColorModel;
import java.awt.image.ImageObserver;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.awt.image.WritableRaster;
import java.awt.image.renderable.RenderableImage;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.text.AttributedCharacterIterator;
import java.text.CharacterIterator;
import java.util.List;
import java.util.Map;

import org.apache.batik.ext.awt.LinearGradientPaint;
import org.apache.batik.ext.awt.MultipleGradientPaint;
import org.apache.batik.ext.awt.RadialGradientPaint;
import org.apache.batik.ext.awt.RenderingHintsKeyExt;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.gvt.PatternPaint;

import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.ImageSize;
import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax;
import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG;
import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
import org.apache.xmlgraphics.java2d.AbstractGraphics2D;
import org.apache.xmlgraphics.java2d.GraphicContext;

import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontSetup;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.pdf.BitmapImage;
import org.apache.fop.pdf.PDFAnnotList;
import org.apache.fop.pdf.PDFColor;
import org.apache.fop.pdf.PDFConformanceException;
import org.apache.fop.pdf.PDFDeviceColorSpace;
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFGState;
import org.apache.fop.pdf.PDFImage;
import org.apache.fop.pdf.PDFImageXObject;
import org.apache.fop.pdf.PDFLink;
import org.apache.fop.pdf.PDFNumber;
import org.apache.fop.pdf.PDFPattern;
import org.apache.fop.pdf.PDFResourceContext;
import org.apache.fop.pdf.PDFResources;
import org.apache.fop.pdf.PDFState;
import org.apache.fop.pdf.PDFText;
import org.apache.fop.pdf.PDFXObject;
import org.apache.fop.render.pdf.ImageRawCCITTFaxAdapter;
import org.apache.fop.render.pdf.ImageRawJPEGAdapter;
import org.apache.fop.render.pdf.ImageRenderedAdapter;
import org.apache.fop.util.ColorExt;

/**
 * PDF Graphics 2D.
 * Used for drawing into a pdf document as if it is a graphics object.
 * This takes a pdf document and draws into it.
 *
 * @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
 * @version $Id$
 * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D
 */
public class PDFGraphics2D extends AbstractGraphics2D {

    private static final AffineTransform IDENTITY_TRANSFORM = new AffineTransform();
    
    /** The number of decimal places. */ 
    private static final int DEC = 8;

    /** Convenience constant for full opacity */
    static final int OPAQUE = 255;
    
    /**
     * the PDF Document being created
     */
    protected PDFDocument pdfDoc;

    /**
     * The current resource context for adding fonts, patterns etc.
     */
    protected PDFResourceContext resourceContext;

    /**
     * The PDF reference of the current page.
     */
    protected String pageRef;

    /**
     * the current state of the pdf graphics
     */
    protected PDFState graphicsState;

    /**
     * The PDF graphics state level that this svg is being drawn into.
     */
    protected int baseLevel = 0;

    /**
     * The count of natively handled images added to document so they receive
     * unique keys.
     */
    protected int nativeCount = 0;

    /**
     * The current font information.
     */
    protected FontInfo fontInfo;

    /**
     * The override font state used when drawing text and the font cannot be
     * set using java fonts.
     */
    protected Font ovFontState = null;

    /**
     * the current stream to add PDF commands to
     */
    protected StringWriter currentStream = new StringWriter();

    /**
     * the current (internal) font name
     */
    protected String currentFontName;

    /**
     * the current font size in millipoints
     */
    protected float currentFontSize;

    /**
     * The output stream for the pdf document.
     * If this is set then it can progressively output
     * the pdf document objects to reduce memory.
     * Especially with images.
     */
    protected OutputStream outputStream = null;

    /**
     * Create a new PDFGraphics2D with the given pdf document info.
     * This is used to create a Graphics object for use inside an already
     * existing document.
     *
     * @param textAsShapes if true then draw text as shapes
     * @param fi the current font information
     * @param doc the pdf document for creating pdf objects
     * @param page the current resource context or page
     * @param pref the PDF reference of the current page
     * @param font the current font name
     * @param size the current font size
     */
    public PDFGraphics2D(boolean textAsShapes, FontInfo fi, PDFDocument doc,
                         PDFResourceContext page, String pref, String font, float size) {
        this(textAsShapes);
        pdfDoc = doc;
        resourceContext = page;
        currentFontName = font;
        currentFontSize = size;
        fontInfo = fi;
        pageRef = pref;
        graphicsState = new PDFState();
    }

    /**
     * Create a new PDFGraphics2D.
     *
     * @param textAsShapes true if drawing text as shapes
     */
    protected PDFGraphics2D(boolean textAsShapes) {
        super(textAsShapes);
    }

    /**
     * This constructor supports the create method.
     * This is not implemented properly.
     *
     * @param g the PDF graphics to make a copy of
     */
    public PDFGraphics2D(PDFGraphics2D g) {
        super(g);
        this.pdfDoc = g.pdfDoc;
        this.resourceContext = g.resourceContext;
        this.currentFontName = g.currentFontName;
        this.currentFontSize = g.currentFontSize;
        this.fontInfo = g.fontInfo;
        this.pageRef = g.pageRef;
        this.graphicsState = g.graphicsState;
        this.currentStream = g.currentStream;
        this.nativeCount = g.nativeCount;
        this.outputStream = g.outputStream;
        this.ovFontState = g.ovFontState;
    }

    /**
     * Creates a new <code>Graphics</code> object that is
     * a copy of this <code>Graphics</code> object.
     * @return     a new graphics context that is a copy of
     * this graphics context.
     */
    public Graphics create() {
        return new PDFGraphics2D(this);
    }

    /**
     * Central handler for IOExceptions for this class.
     * @param ioe IOException to handle
     */
    protected void handleIOException(IOException ioe) {
        //TODO Surely, there's a better way to do this.
        ioe.printStackTrace();
    }

    /**
     * This method is used by PDFDocumentGraphics2D to prepare a new page if
     * necessary.
     */
    protected void preparePainting() {
        //nop, used by PDFDocumentGraphics2D
    }

    /**
     * Set the PDF state to use when starting to draw
     * into the PDF graphics.
     *
     * @param state the PDF state
     */
    public void setPDFState(PDFState state) {
        graphicsState = state;
        baseLevel = graphicsState.getStackLevel();
    }

    /**
     * Set the output stream that this PDF document is
     * being drawn to. This is so that it can progressively
     * use the PDF document to output data such as images.
     * This results in a significant saving on memory.
     *
     * @param os the output stream that is being used for the PDF document
     */
    public void setOutputStream(OutputStream os) {
        outputStream = os;
    }

    /**
     * Get the string containing all the commands written into this
     * Grpahics.
     * @return the string containing the PDF markup
     */
    public String getString() {
        return currentStream.toString();
    }

    /**
     * Get the string buffer from the currentStream, containing all
     * the commands written into this Grpahics so far.
     * @return the StringBuffer containing the PDF markup
     */
    public StringBuffer getBuffer() {
        return currentStream.getBuffer();
    }

    /**
     * Set the Grpahics context.
     * @param c the graphics context to use
     */
    public void setGraphicContext(GraphicContext c) {
        gc = c;
        setPrivateHints();
    }

    private void setPrivateHints() {
        setRenderingHint(RenderingHintsKeyExt.KEY_AVOID_TILE_PAINTING, 
                RenderingHintsKeyExt.VALUE_AVOID_TILE_PAINTING_ON);
    }
    
    /**
     * Set the override font state for drawing text.
     * This is used by the PDF text painter so that it can temporarily
     * set the font state when a java font cannot be used.
     * The next drawString will use this font state.
     *
     * @param infont the font state to use
     */
    public void setOverrideFontState(Font infont) {
        ovFontState = infont;
    }

    /**
     * Restore the PDF graphics state to the starting state level.
     */
    /* seems not to be used
    public void restorePDFState() {
        for (int count = graphicsState.getStackLevel(); count > baseLevel; count--) {
            currentStream.write("Q\n");
        }
        graphicsState.restoreLevel(baseLevel);
    }*/

    private void concatMatrix(double[] matrix) {
        currentStream.write(PDFNumber.doubleOut(matrix[0], DEC) + " "
                + PDFNumber.doubleOut(matrix[1], DEC) + " "
                + PDFNumber.doubleOut(matrix[2], DEC) + " "
                + PDFNumber.doubleOut(matrix[3], DEC) + " "
                + PDFNumber.doubleOut(matrix[4], DEC) + " "
                + PDFNumber.doubleOut(matrix[5], DEC) + " cm\n");
    }

    private void concatMatrix(AffineTransform transform) {
        if (!transform.isIdentity()) {
            double[] matrix = new double[6];
            transform.getMatrix(matrix);
            concatMatrix(matrix);
        }
    }
    
    /**
     * This is mainly used for shading patterns which use the document-global coordinate system
     * instead of the local one.
     * @return the transformation matrix that established the basic user space for this document
     */
    protected AffineTransform getBaseTransform() {
        AffineTransform at = new AffineTransform(graphicsState.getTransform());
        return at;
    }
    
    /**
     * This is a pdf specific method used to add a link to the
     * pdf document.
     *
     * @param bounds the bounds of the link in user coordinates
     * @param trans the transform of the current drawing position
     * @param dest the PDF destination
     * @param linkType the type of link, internal or external
     */
    public void addLink(Rectangle2D bounds, AffineTransform trans, String dest, int linkType) {
        if (!pdfDoc.getProfile().isAnnotationAllowed()) {
            return;
        }
        preparePainting();
        AffineTransform at = getTransform();
        Shape b = at.createTransformedShape(bounds);
        b = trans.createTransformedShape(b);
        if (b != null) {
            Rectangle rect = b.getBounds();

            if (linkType != PDFLink.EXTERNAL) {
                String pdfdest = "/FitR " + dest;
                resourceContext.addAnnotation(
                    pdfDoc.getFactory().makeLink(rect, pageRef, pdfdest));
            } else {
                resourceContext.addAnnotation(
                    pdfDoc.getFactory().makeLink(rect, dest, linkType, 0));
            }
        }
    }

    /**
     * Add a natively handled image directly to the PDF document.
     * This is used by the PDFImageElementBridge to draw a natively handled image
     * (like JPEG or CCITT images)
     * directly into the PDF document rather than converting the image into
     * a bitmap and increasing the size.
     *
     * @param image the image to draw
     * @param x the x position
     * @param y the y position
     * @param width the width to draw the image
     * @param height the height to draw the image
     */
    void addNativeImage(org.apache.xmlgraphics.image.loader.Image image, float x, float y, 
                             float width, float height) {
        preparePainting();
        String key = image.getInfo().getOriginalURI();
        if (key == null) {
            // Need to include hash code as when invoked from FO you
            // may have several 'independent' PDFGraphics2D so the
            // count is not enough.
            key = "__AddNative_" + hashCode() + "_" + nativeCount; 
            nativeCount++;
        }
        
        PDFImage pdfImage;
        if (image instanceof ImageRawJPEG) {
            pdfImage = new ImageRawJPEGAdapter((ImageRawJPEG)image, key);
        } else if (image instanceof ImageRawCCITTFax) {
            pdfImage = new ImageRawCCITTFaxAdapter((ImageRawCCITTFax)image, key);
        } else {
            throw new IllegalArgumentException(
                    "Unsupported Image subclass: " + image.getClass().getName());
        }
        
        PDFXObject xObject = this.pdfDoc.addImage(resourceContext, pdfImage);
        if (outputStream != null) {
            try {
                this.pdfDoc.output(outputStream);
            } catch (IOException ioe) {
                // ignore exception, will be thrown again later
            }
        }

        AffineTransform at = new AffineTransform();
        at.translate(x, y);
        useXObject(xObject, at, width, height);
    }

    /**
     * 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
     * space. Transparent pixels in the image do not affect whatever
     * pixels are already there.
     * <p>
     * This method returns immediately in all cases, even if the
     * complete image has not yet been loaded, and it has not been dithered
     * and converted for the current output device.
     * <p>
     * If the image has not yet been completely loaded, then
     * <code>drawImage</code> returns <code>false</code>. As more of
     * the image becomes available, the process that draws the image notifies
     * the specified image observer.
     * @param    img the specified image to be drawn.
     * @param    x   the <i>x</i> coordinate.
     * @param    y   the <i>y</i> coordinate.
     * @param    observer    object to be notified as more of
     * the image is converted.
     * @return true if the image was drawn
     * @see      java.awt.Image
     * @see      java.awt.image.ImageObserver
     * @see      java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
     */
    public boolean drawImage(Image img, int x, int y,
                             ImageObserver observer) {
        preparePainting();

        int width = img.getWidth(observer);
        int height = img.getHeight(observer);

        if (width == -1 || height == -1) {
            return false;
        }

        return drawImage(img, x, y, width, height, observer);
    }

    private BufferedImage buildBufferedImage(Dimension size) {
        return new BufferedImage(size.width, size.height,
                                 BufferedImage.TYPE_INT_ARGB);
    }

    /** {@inheritDoc} */
    public boolean drawImage(Image img, int x, int y, int width, int height,
                               ImageObserver observer) {
        preparePainting();
        // first we look to see if we've already added this image to
        // the pdf document. If so, we just reuse the reference;
        // otherwise we have to build a FopImage and add it to the pdf
        // document
        String key = "TempImage:" + img.toString();
        PDFXObject xObject = pdfDoc.getXObject(key);
        if (xObject == null) {
            // OK, have to build and add a PDF image

            Dimension size = new Dimension(width, height);
            BufferedImage buf = buildBufferedImage(size);

            java.awt.Graphics2D g = buf.createGraphics();
            g.setComposite(AlphaComposite.SrcOver);
            g.setBackground(new Color(1, 1, 1, 0));
            g.setPaint(new Color(1, 1, 1, 0));
            g.fillRect(0, 0, width, height);
            g.clip(new Rectangle(0, 0, buf.getWidth(), buf.getHeight()));
            g.setComposite(gc.getComposite());

            if (!g.drawImage(img, 0, 0, buf.getWidth(), buf.getHeight(), observer)) {
                return false;
            }
            g.dispose();

            xObject = addRenderedImage(key, buf);
        } else {
            resourceContext.getPDFResources().addXObject(xObject);
        }

        AffineTransform at = new AffineTransform();
        at.translate(x, y);
        useXObject(xObject, at, width, height);
        return true;
    }

    /**
     * Disposes of this graphics context and releases
     * any system resources that it is using.
     * A <code>Graphics</code> object cannot be used after
     * <code>dispose</code>has been called.
     * <p>
     * When a Java program runs, a large number of <code>Graphics</code>
     * objects can be created within a short time frame.
     * Although the finalization process of the garbage collector
     * also disposes of the same system resources, it is preferable
     * to manually free the associated resources by calling this
     * method rather than to rely on a finalization process which
     * may not run to completion for a long period of time.
     * <p>
     * Graphics objects which are provided as arguments to the
     * <code>paint</code> and <code>update</code> methods
     * of components are automatically released by the system when
     * those methods return. For efficiency, programmers should
     * call <code>dispose</code> when finished using
     * a <code>Graphics</code> object only if it was created
     * directly from a component or another <code>Graphics</code> object.
     * @see         java.awt.Graphics#finalize
     * @see         java.awt.Component#paint
     * @see         java.awt.Component#update
     * @see         java.awt.Component#getGraphics
     * @see         java.awt.Graphics#create
     */
    public void dispose() {
        pdfDoc = null;
        fontInfo = null;
        currentStream = null;
        currentFontName = null;
    }

    /**
     * Strokes the outline of a <code>Shape</code> using the settings of the
     * current <code>Graphics2D</code> context.  The rendering attributes
     * applied include the <code>Clip</code>, <code>Transform</code>,
     * <code>Paint</code>, <code>Composite</code> and
     * <code>Stroke</code> attributes.
     * @param s the <code>Shape</code> to be rendered
     * @see #setStroke
     * @see #setPaint
     * @see java.awt.Graphics#setColor
     * @see #transform
     * @see #setTransform
     * @see #clip
     * @see #setClip
     * @see #setComposite
     */
    public void draw(Shape s) {
        preparePainting();

        //Transparency shortcut
        Color c;
        c = getColor();
        if (c.getAlpha() == 0) {
            return;
        }

        AffineTransform trans = getTransform();
        double[] tranvals = new double[6];
        trans.getMatrix(tranvals);

        Shape imclip = getClip();
        boolean newClip = graphicsState.checkClip(imclip);
        boolean newTransform = graphicsState.checkTransform(trans)
                               && !trans.isIdentity();

        if (newClip || newTransform) {
            currentStream.write("q\n");
            graphicsState.push();
            if (newTransform) {
                concatMatrix(tranvals);
            }
            if (newClip) {
                writeClip(imclip);
            }
        }

        applyAlpha(OPAQUE, c.getAlpha());

        c = getColor();
        applyColor(c, false);
        c = getBackground();
        applyColor(c, true);

        Paint paint = getPaint();
        if (graphicsState.setPaint(paint)) {
            if (!applyPaint(paint, false)) {
                // Stroke the shape and use it to 'clip'
                // the paint contents.
                Shape ss = getStroke().createStrokedShape(s);
                applyUnknownPaint(paint, ss);

                if (newClip || newTransform) {
                    currentStream.write("Q\n");
                    graphicsState.pop();
                }
                return;
            }
        }
        applyStroke(getStroke());

        PathIterator iter = s.getPathIterator(IDENTITY_TRANSFORM);
        processPathIterator(iter);
        doDrawing(false, true, false);
        if (newClip || newTransform) {
            currentStream.write("Q\n");
            graphicsState.pop();
        }
    }
    
/*
    // in theory we could set the clip using these methods
    // it doesn't seem to improve the file sizes much
    // and makes everything more complicated

    Shape lastClip = null;

    public void clip(Shape cl) {
        super.clip(cl);
        Shape newClip = getClip();
        if (newClip == null || lastClip == null
                || !(new Area(newClip).equals(new Area(lastClip)))) {
        graphicsState.setClip(newClip);
        writeClip(newClip);
        }

        lastClip = newClip;
    }

    public void setClip(Shape cl) {
        super.setClip(cl);
        Shape newClip = getClip();
        if (newClip == null || lastClip == null
                || !(new Area(newClip).equals(new Area(lastClip)))) {
        for (int count = graphicsState.getStackLevel(); count > baseLevel; count--) {
            currentStream.write("Q\n");
        }
        graphicsState.restoreLevel(baseLevel);
        currentStream.write("q\n");
        graphicsState.push();
        if (newClip != null) {
            graphicsState.setClip(newClip);
        }
        writeClip(newClip);
        }

        lastClip = newClip;
    }
*/

    /**
     * Set the clipping shape for future PDF drawing in the current graphics state.
     * This sets creates and writes a clipping shape that will apply
     * to future drawings in the current graphics state.
     *
     * @param s the clipping shape
     */
    protected void writeClip(Shape s) {
        if (s == null) {
            return;
        }
        preparePainting();
        PathIterator iter = s.getPathIterator(IDENTITY_TRANSFORM);
        processPathIterator(iter);
        // clip area
        currentStream.write("W\n");
        currentStream.write("n\n");
    }

    /**
     * Apply the java Color to PDF.
     * This converts the java colour to a PDF colour and
     * sets it for the next drawing.
     *
     * @param col the java colour
     * @param fill true if the colour will be used for filling
     */
    protected void applyColor(Color col, boolean fill) {
        preparePainting();

        Color c = col;
        if (col instanceof ColorExt) {
            PDFColor currentColour = new PDFColor(this.pdfDoc, col);
            currentStream.write(currentColour.getColorSpaceOut(fill));
        } else if (c.getColorSpace().getType()
                == ColorSpace.TYPE_RGB) {
            PDFColor currentColour = new PDFColor(c.getRed(), c.getGreen(),
                                         c.getBlue());
            currentStream.write(currentColour.getColorSpaceOut(fill));
        } else if (c.getColorSpace().getType()
                   == ColorSpace.TYPE_CMYK) {
            if (pdfDoc.getProfile().getPDFAMode().isPDFA1LevelB()) {
                //See PDF/A-1, ISO 19005:1:2005(E), 6.2.3.3
                //FOP is currently restricted to DeviceRGB if PDF/A-1 is active.
                throw new PDFConformanceException(
                        "PDF/A-1 does not allow mixing DeviceRGB and DeviceCMYK.");
            }
            float[] cComps = c.getColorComponents(new float[3]);
            double[] cmyk = new double[3];
            for (int i = 0; i < 3; i++) {
                // convert the float elements to doubles for pdf
                cmyk[i] = cComps[i];
            }
            PDFColor currentColour = new PDFColor(cmyk[0], cmyk[1], cmyk[2], cmyk[3]);
            currentStream.write(currentColour.getColorSpaceOut(fill));
        } else if (c.getColorSpace().getType()
                   == ColorSpace.TYPE_2CLR) {
            // used for black/magenta
            float[] cComps = c.getColorComponents(new float[1]);
            double[] blackMagenta = new double[1];
            for (int i = 0; i < 1; i++) {
                blackMagenta[i] = cComps[i];
            }
            //PDFColor  currentColour = new PDFColor(blackMagenta[0], blackMagenta[1]);
            //currentStream.write(currentColour.getColorSpaceOut(fill));
        } else {
            throw new UnsupportedOperationException(
                    "Color Space not supported by PDFGraphics2D");
        }
    }

    /**
     * Apply the java paint to the PDF.
     * This takes the java paint sets up the appropraite PDF commands
     * for the drawing with that paint.
     * Currently this supports the gradients and patterns from batik.
     *
     * @param paint the paint to convert to PDF
     * @param fill true if the paint should be set for filling
     * @return true if the paint is handled natively, false if the paint should be rasterized
     */
    protected boolean applyPaint(Paint paint, boolean fill) {
        preparePainting();

        if (paint instanceof Color) {
            return true;
        }
        // convert java.awt.GradientPaint to LinearGradientPaint to avoid rasterization
        if (paint instanceof GradientPaint) {
            GradientPaint gpaint = (GradientPaint) paint;
            paint = new LinearGradientPaint(
                    (float) gpaint.getPoint1().getX(),
                    (float) gpaint.getPoint1().getY(),
                    (float) gpaint.getPoint2().getX(),
                    (float) gpaint.getPoint2().getY(), 
                    new float[] {0, 1}, 
                    new Color[] {gpaint.getColor1(), gpaint.getColor2()},
                    gpaint.isCyclic() ? LinearGradientPaint.REPEAT : LinearGradientPaint.NO_CYCLE);
        }
        if (paint instanceof LinearGradientPaint) {
            LinearGradientPaint gp = (LinearGradientPaint)paint;

            // This code currently doesn't support 'repeat'.
            // For linear gradients it is possible to construct
            // a 'tile' that is repeated with a PDF pattern, but
            // it would be very tricky as you would have to rotate
            // the coordinate system so the repeat was axially
            // aligned.  At this point I'm just going to rasterize it.
            MultipleGradientPaint.CycleMethodEnum cycle = gp.getCycleMethod();
            if (cycle != MultipleGradientPaint.NO_CYCLE) {
                return false;
            }

            Color[] cols = gp.getColors();
            float[] fractions = gp.getFractions();

            // Build proper transform from gradient space to page space
            // ('Patterns' don't get userspace transform).
            AffineTransform transform;
            transform = new AffineTransform(getBaseTransform());
            transform.concatenate(getTransform());
            transform.concatenate(gp.getTransform());

            List theMatrix = new java.util.ArrayList();
            double [] mat = new double[6];
            transform.getMatrix(mat);
            for (int idx = 0; idx < mat.length; idx++) {
                theMatrix.add(new Double(mat[idx]));
            }

            Point2D p1 = gp.getStartPoint();
            Point2D p2 = gp.getEndPoint();
            List theCoords = new java.util.ArrayList();
            theCoords.add(new Double(p1.getX()));
            theCoords.add(new Double(p1.getY()));
            theCoords.add(new Double(p2.getX()));
            theCoords.add(new Double(p2.getY()));

            List theExtend = new java.util.ArrayList();
            theExtend.add(new Boolean(true));
            theExtend.add(new Boolean(true));

            List theDomain = new java.util.ArrayList();
            theDomain.add(new Double(0));
            theDomain.add(new Double(1));

            List theEncode = new java.util.ArrayList();
            theEncode.add(new Double(0));
            theEncode.add(new Double(1));
            theEncode.add(new Double(0));
            theEncode.add(new Double(1));

            List theBounds = new java.util.ArrayList();

            List someColors = new java.util.ArrayList();

            for (int count = 0; count < cols.length; count++) {
                Color c1 = cols[count];
                if (c1.getAlpha() != 255) {
                    return false;  // PDF can't do alpha
                }

                PDFColor color1 = new PDFColor(c1.getRed(), c1.getGreen(),
                                               c1.getBlue());
                someColors.add(color1);
                if (count > 0 && count < cols.length - 1) {
                    theBounds.add(new Double(fractions[count]));
                }
            }

            PDFDeviceColorSpace aColorSpace;
            aColorSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB);
            PDFPattern myPat = pdfDoc.getFactory().makeGradient(
                    resourceContext, false, aColorSpace,
                    someColors, theBounds, theCoords, theMatrix);
            currentStream.write(myPat.getColorSpaceOut(fill));

            return true;
        }
        if (paint instanceof RadialGradientPaint) {
            RadialGradientPaint rgp = (RadialGradientPaint)paint;

            // There is essentially no way to support repeate
            // in PDF for radial gradients (the one option would
            // be to 'grow' the outer circle until it fully covered
            // the bounds and then grow the stops accordingly, the
            // problem is that this may require an extremely large
            // number of stops for cases where the focus is near
            // the edge of the outer circle).  so we rasterize.
            MultipleGradientPaint.CycleMethodEnum cycle = rgp.getCycleMethod();
            if (cycle != MultipleGradientPaint.NO_CYCLE) {
                return false;
            }

            AffineTransform transform;
            transform = new AffineTransform(getBaseTransform());
            transform.concatenate(getTransform());
            transform.concatenate(rgp.getTransform());

            List theMatrix = new java.util.ArrayList();
            double [] mat = new double[6];
            transform.getMatrix(mat);
            for (int idx = 0; idx < mat.length; idx++) {
                theMatrix.add(new Double(mat[idx]));
            }

            double ar = rgp.getRadius();
            Point2D ac = rgp.getCenterPoint();
            Point2D af = rgp.getFocusPoint();

            List theCoords = new java.util.ArrayList();
            double dx = af.getX() - ac.getX();
            double dy = af.getY() - ac.getY();
            double d = Math.sqrt(dx * dx + dy * dy);
            if (d > ar) {
                // the center point af must be within the circle with
                // radius ar centered at ac so limit it to that.
                double scale = (ar * .9999) / d;
                dx = dx * scale;
                dy = dy * scale;
            }

            theCoords.add(new Double(ac.getX() + dx)); // Fx
            theCoords.add(new Double(ac.getY() + dy)); // Fy
            theCoords.add(new Double(0));
            theCoords.add(new Double(ac.getX()));
            theCoords.add(new Double(ac.getY()));
            theCoords.add(new Double(ar));

            Color[] cols = rgp.getColors();
            List someColors = new java.util.ArrayList();
            for (int count = 0; count < cols.length; count++) {
                Color cc = cols[count];
                if (cc.getAlpha() != 255) {
                    return false;  // PDF can't do alpha
                }

                someColors.add(new PDFColor(cc.getRed(), cc.getGreen(), 
                                            cc.getBlue()));
            }

            float[] fractions = rgp.getFractions();
            List theBounds = new java.util.ArrayList();
            for (int count = 1; count < fractions.length - 1; count++) {
                float offset = fractions[count];
                theBounds.add(new Double(offset));
            }
            PDFDeviceColorSpace colSpace;
            colSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_RGB);

            PDFPattern myPat = pdfDoc.getFactory().makeGradient
                (resourceContext, true, colSpace,
                 someColors, theBounds, theCoords, theMatrix);

            currentStream.write(myPat.getColorSpaceOut(fill));

            return true;
        } 
        if (paint instanceof PatternPaint) {
            PatternPaint pp = (PatternPaint)paint;
            return createPattern(pp, fill);
        }
        return false; // unknown paint
    }

    private boolean createPattern(PatternPaint pp, boolean fill) {
        preparePainting();

        FontInfo specialFontInfo = new FontInfo();
        FontSetup.setup(specialFontInfo, null, null);

        PDFResources res = pdfDoc.getFactory().makeResources();
        PDFResourceContext context = new PDFResourceContext(res);
        PDFGraphics2D pattGraphic = new PDFGraphics2D(textAsShapes, specialFontInfo,
                                        pdfDoc, context, pageRef,
                                        "", 0);
        pattGraphic.setGraphicContext(new GraphicContext());
        pattGraphic.gc.validateTransformStack();
        pattGraphic.setRenderingHints(this.getRenderingHints());
        pattGraphic.setOutputStream(outputStream);

        GraphicsNode gn = pp.getGraphicsNode();
        Rectangle2D gnBBox = gn.getBounds();
        Rectangle2D rect = pp.getPatternRect();

        // if (!pp.getOverflow()) {
            gn.paint(pattGraphic);
        // } else {
        // /* Commented out until SVN version of Batik is included */
        //     // For overflow we need to paint the content from
        //     // all the tiles who's overflow will intersect one
        //     // tile (left->right, top->bottom).  Then we can
        //     // simply replicate that tile as normal.
        //     double gnMinX = gnBBox.getX();
        //     double gnMaxX = gnBBox.getX() + gnBBox.getWidth();
        //     double gnMinY = gnBBox.getY();
        //     double gnMaxY = gnBBox.getY() + gnBBox.getHeight();
        //     double patMaxX = rect.getX() + rect.getWidth();
        //     double patMaxY = rect.getY() + rect.getHeight();
        //     double stepX = rect.getWidth();
        //     double stepY = rect.getHeight();            
        // 
        //     int startX = (int)((rect.getX() - gnMaxX)/stepX);
        //     int startY = (int)((rect.getY() - gnMaxY)/stepY);
        // 
        //     int endX   = (int)((patMaxX - gnMinX)/stepX);
        //     int endY   = (int)((patMaxY - gnMinY)/stepY);
        // 
        //     pattGraphic.translate(startX*stepX, startY*stepY);
        //     for (int yIdx=startY; yIdx<=endY; yIdx++) {
        //         for (int xIdx=startX; xIdx<=endX; xIdx++) {
        //             gn.paint(pattGraphic);
        //             pattGraphic.translate(stepX,0);
        //         }
        //         pattGraphic.translate(-(endX-startX+1)*stepX, stepY);
        //     }
        // }

        List bbox = new java.util.ArrayList();
        bbox.add(new Double(rect.getX()));
        bbox.add(new Double(rect.getHeight() + rect.getY()));
        bbox.add(new Double(rect.getWidth() + rect.getX()));
        bbox.add(new Double(rect.getY()));

        AffineTransform transform;
        transform = new AffineTransform(getBaseTransform());
        transform.concatenate(getTransform());
        transform.concatenate(pp.getPatternTransform());

        List theMatrix = new java.util.ArrayList();
        double [] mat = new double[6];
        transform.getMatrix(mat);
        for (int idx = 0; idx < mat.length; idx++) {
            theMatrix.add(new Double(mat[idx]));
        }

        /** @todo see if pdfDoc and res can be linked here,
        (currently res <> PDFDocument's resources) so addFonts() 
        can be moved to PDFDocument class */
        res.addFonts(pdfDoc, specialFontInfo);

        PDFPattern myPat = pdfDoc.getFactory().makePattern(
                                resourceContext, 1, res, 1, 1, bbox,
                                rect.getWidth(), rect.getHeight(),
                                theMatrix, null, 
                                pattGraphic.getBuffer());

        currentStream.write(myPat.getColorSpaceOut(fill));

        PDFAnnotList annots = context.getAnnotations();
        if (annots != null) {
            this.pdfDoc.addObject(annots);
        }

        if (outputStream != null) {
            try {
                this.pdfDoc.output(outputStream);
            } catch (IOException ioe) {
                // ignore exception, will be thrown again later
            }
        }
        return true;
    }

    protected boolean applyUnknownPaint(Paint paint, Shape shape) {
        preparePainting();

        Shape clip = getClip();
        Rectangle2D usrClipBounds, usrBounds;
        usrBounds = shape.getBounds2D();
        if (clip != null) {
            usrClipBounds  = clip.getBounds2D();
            if (!usrClipBounds.intersects(usrBounds)) {
                return true;
            }
            Rectangle2D.intersect(usrBounds, usrClipBounds, usrBounds);
        }
        double usrX = usrBounds.getX();
        double usrY = usrBounds.getY();
        double usrW = usrBounds.getWidth();
        double usrH = usrBounds.getHeight();

        Rectangle devShapeBounds, devClipBounds, devBounds;
        AffineTransform at = getTransform();
        devShapeBounds = at.createTransformedShape(shape).getBounds();
        if (clip != null) {
            devClipBounds  = at.createTransformedShape(clip).getBounds();
            if (!devClipBounds.intersects(devShapeBounds)) {
                return true;
            }
            devBounds = devShapeBounds.intersection(devClipBounds);
        } else {
            devBounds = devShapeBounds;
        }
        int devX = devBounds.x;
        int devY = devBounds.y;
        int devW = devBounds.width;
        int devH = devBounds.height;

        ColorSpace rgbCS = ColorSpace.getInstance(ColorSpace.CS_sRGB);
        ColorModel rgbCM = new DirectColorModel
            (rgbCS, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000,
             false, DataBuffer.TYPE_BYTE);

        PaintContext pctx = paint.createContext(rgbCM, devBounds, usrBounds, 
                                                at, getRenderingHints());
        PDFXObject imageInfo = pdfDoc.getXObject
            ("TempImage:" + pctx.toString());
        if (imageInfo != null) {
            resourceContext.getPDFResources().addXObject(imageInfo);
        } else {
            Raster r = pctx.getRaster(devX, devY, devW, devH);
            WritableRaster wr = (WritableRaster)r;
            wr = wr.createWritableTranslatedChild(0, 0);

            ColorModel pcm = pctx.getColorModel();
            BufferedImage bi = new BufferedImage
                (pcm, wr, pcm.isAlphaPremultiplied(), null);
            final byte[] rgb  = new byte[devW * devH * 3];
            final int[]  line = new int[devW];
            final byte[] mask;
            int x, y, val, rgbIdx = 0;
        
            if (pcm.hasAlpha()) {
                mask = new byte[devW * devH];
                int maskIdx = 0;
                for (y = 0; y < devH; y++) {
                    bi.getRGB(0, y, devW, 1, line, 0, devW);
                    for (x = 0; x < devW; x++) {
                        val = line[x];
                        mask[maskIdx++] = (byte)(val >>> 24);
                        rgb[rgbIdx++]   = (byte)((val >> 16) & 0x0FF);
                        rgb[rgbIdx++]   = (byte)((val >> 8 ) & 0x0FF);
                        rgb[rgbIdx++]   = (byte)((val      ) & 0x0FF);
                    }
                }
            } else {
                mask = null;
                for (y = 0; y < devH; y++) {
                    bi.getRGB(0, y, devW, 1, line, 0, devW);
                    for (x = 0; x < devW; x++) {
                        val = line[x];
                        rgb[rgbIdx++]  = (byte)((val >> 16) & 0x0FF);
                        rgb[rgbIdx++]  = (byte)((val >> 8 ) & 0x0FF);
                        rgb[rgbIdx++]  = (byte)((val      ) & 0x0FF);
                    }
                }
            }

            String maskRef = null;
            if (mask != null) {
                BitmapImage fopimg = new BitmapImage
                    ("TempImageMask:" + pctx.toString(), devW, devH, mask, null);
                fopimg.setColorSpace(new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_GRAY));
                PDFImageXObject xobj = pdfDoc.addImage(resourceContext, fopimg);
                maskRef = xobj.referencePDF();

                if (outputStream != null) {
                    try {
                        this.pdfDoc.output(outputStream);
                    } catch (IOException ioe) {
                        // ignore exception, will be thrown again later
                    }
                }
            }
            BitmapImage fopimg;
            fopimg = new BitmapImage("TempImage:" + pctx.toString(),
                                     devW, devH, rgb, maskRef);
            fopimg.setTransparent(new PDFColor(255, 255, 255));
            imageInfo = pdfDoc.addImage(resourceContext, fopimg);
            if (outputStream != null) {
                try {
                    this.pdfDoc.output(outputStream);
                } catch (IOException ioe) {
                    // ignore exception, will be thrown again later
                }
            }
        }

        currentStream.write("q\n");
        writeClip(shape);
        currentStream.write("" + usrW + " 0 0 " + (-usrH) + " " + usrX
                            + " " + (usrY + usrH) + " cm\n"
                            + imageInfo.getName() + " Do\nQ\n");
        return true;
    }

    /**
     * Apply the stroke to the PDF.
     * This takes the java stroke and outputs the appropriate settings
     * to the PDF so that the stroke attributes are handled.
     *
     * @param stroke the java stroke
     */
    protected void applyStroke(Stroke stroke) {
        preparePainting();
        if (stroke instanceof BasicStroke) {
            BasicStroke bs = (BasicStroke)stroke;

            float[] da = bs.getDashArray();
            if (da != null) {
                currentStream.write("[");
                for (int count = 0; count < da.length; count++) {
                    currentStream.write(PDFNumber.doubleOut(da[count]));
                    if (count < da.length - 1) {
                        currentStream.write(" ");
                    }
                }
                currentStream.write("] ");
                float offset = bs.getDashPhase();
                currentStream.write(PDFNumber.doubleOut(offset) + " d\n");
            }
            int ec = bs.getEndCap();
            switch (ec) {
            case BasicStroke.CAP_BUTT:
                currentStream.write(0 + " J\n");
                break;
            case BasicStroke.CAP_ROUND:
                currentStream.write(1 + " J\n");
                break;
            case BasicStroke.CAP_SQUARE:
                currentStream.write(2 + " J\n");
                break;
            }

            int lj = bs.getLineJoin();
            switch (lj) {
            case BasicStroke.JOIN_MITER:
                currentStream.write(0 + " j\n");
                break;
            case BasicStroke.JOIN_ROUND:
                currentStream.write(1 + " j\n");
                break;
            case BasicStroke.JOIN_BEVEL:
                currentStream.write(2 + " j\n");
                break;
            }
            float lw = bs.getLineWidth();
            currentStream.write(PDFNumber.doubleOut(lw) + " w\n");

            float ml = bs.getMiterLimit();
            currentStream.write(PDFNumber.doubleOut(ml) + " M\n");
        }
    }

    /** {@inheritDoc} */
    public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
        String key = "TempImage:" + img.toString();
        drawInnerRenderedImage(key, img, xform);
    }

    /** {@inheritDoc} */
    public void drawInnerRenderedImage(String key, RenderedImage img, AffineTransform xform) {
        preparePainting();
        PDFXObject xObject = pdfDoc.getXObject(key);
        if (xObject == null) {
            xObject = addRenderedImage(key, img);
        } else {
            resourceContext.getPDFResources().addXObject(xObject);
        }

        useXObject(xObject, xform, img.getWidth(), img.getHeight());
    }

    private void useXObject(PDFXObject xObject, AffineTransform xform, float width, float height) {
        // now do any transformation required and add the actual image
        // placement instance
        currentStream.write("q\n");
        concatMatrix(getTransform());
        Shape imclip = getClip();
        writeClip(imclip);
        concatMatrix(xform);
        String w = PDFNumber.doubleOut(width, DEC);
        String h = PDFNumber.doubleOut(height, DEC);
        currentStream.write("" + w + " 0 0 -" + h + " 0 " + h + " cm\n"
                + xObject.getName() + " Do\nQ\n");
    }

    private PDFXObject addRenderedImage(String key, RenderedImage img) {
        ImageInfo info = new ImageInfo(null, "image/unknown");
        ImageSize size = new ImageSize(img.getWidth(), img.getHeight(), 72);
        info.setSize(size);
        ImageRendered imgRend = new ImageRendered(info, img, null);
        ImageRenderedAdapter adapter = new ImageRenderedAdapter(imgRend, key);
        PDFXObject xObject = pdfDoc.addImage(resourceContext, adapter);
        if (outputStream != null) {
            try {
                this.pdfDoc.output(outputStream);
            } catch (IOException ioe) {
                // ignore exception, will be thrown again later
            }
        }
        return xObject;
    }

    /** {@inheritDoc} */
    public void drawRenderableImage(RenderableImage img,
                                    AffineTransform xform) {
        //TODO Check if this is good enough
        drawRenderedImage(img.createDefaultRendering(), xform);
    }

    /**
     * Renders the text specified by the specified <code>String</code>,
     * using the current <code>Font</code> and <code>Paint</code> attributes
     * in the <code>Graphics2D</code> context.
     * The baseline of the first character is at position
     * (<i>x</i>,&nbsp;<i>y</i>) in the User Space.
     * The rendering attributes applied include the <code>Clip</code>,
     * <code>Transform</code>, <code>Paint</code>, <code>Font</code> and
     * <code>Composite</code> attributes. For characters in script systems
     * such as Hebrew and Arabic, the glyphs can be rendered from right to
     * left, in which case the coordinate supplied is the location of the
     * leftmost character on the baseline.
     * @param s the <code>String</code> to be rendered
     * @param x the coordinate where the <code>String</code>
     * should be rendered
     * @param y the coordinate where the <code>String</code>
     * should be rendered
     * @see #setPaint
     * @see java.awt.Graphics#setColor
     * @see java.awt.Graphics#setFont
     * @see #setTransform
     * @see #setComposite
     * @see #setClip
     */
    public void drawString(String s, float x, float y) {
        preparePainting();

        Font fontState;
        AffineTransform fontTransform = null;
        if (ovFontState == null) {
            java.awt.Font gFont = getFont();
            fontTransform = gFont.getTransform();
            fontState = getInternalFontForAWTFont(gFont);
        } else {
            fontState = fontInfo.getFontInstance(
                    ovFontState.getFontTriplet(), ovFontState.getFontSize());
            ovFontState = null;
        }
        updateCurrentFont(fontState);

        currentStream.write("q\n");

        Color c = getColor();
        applyColor(c, true);
        applyPaint(getPaint(), true);
        applyAlpha(c.getAlpha(), OPAQUE);

        Map kerning = fontState.getKerning();
        boolean kerningAvailable = (kerning != null && !kerning.isEmpty());

        boolean useMultiByte = isMultiByteFont(currentFontName);

        // String startText = useMultiByte ? "<FEFF" : "(";
        String startText = useMultiByte ? "<" : "(";
        String endText = useMultiByte ? "> " : ") ";

        AffineTransform trans = getTransform();
        //trans.translate(x, y);
        double[] vals = new double[6];
        trans.getMatrix(vals);

        concatMatrix(vals);
        Shape imclip = getClip();
        writeClip(imclip);

        currentStream.write("BT\n");

        AffineTransform localTransform = new AffineTransform();
        localTransform.translate(x, y);
        if (fontTransform != null) {
            localTransform.concatenate(fontTransform);
        }
        localTransform.scale(1, -1);
        double[] lt = new double[6];
        localTransform.getMatrix(lt);
        currentStream.write(PDFNumber.doubleOut(lt[0]) + " "
                + PDFNumber.doubleOut(lt[1]) + " " + PDFNumber.doubleOut(lt[2]) + " "
                + PDFNumber.doubleOut(lt[3]) + " " + PDFNumber.doubleOut(lt[4]) + " "
                + PDFNumber.doubleOut(lt[5]) + " Tm [" + startText);

        int l = s.length();

        for (int i = 0; i < l; i++) {
            char ch = fontState.mapChar(s.charAt(i));

            if (!useMultiByte) {
                if (ch > 127) {
                    currentStream.write("\\");
                    currentStream.write(Integer.toOctalString((int)ch));
                } else {
                    switch (ch) {
                    case '(':
                    case ')':
                    case '\\':
                        currentStream.write("\\");
                        break;
                    default:
                    }
                    currentStream.write(ch);
                }
            } else {
                currentStream.write(PDFText.toUnicodeHex(ch));
            }

            if (kerningAvailable && (i + 1) < l) {
                addKerning(currentStream, (new Integer((int)ch)),
                           (new Integer((int)fontState.mapChar(s.charAt(i + 1)))),
                           kerning, startText, endText);
            }

        }
        currentStream.write(endText);

        currentStream.write("] TJ\n");
        currentStream.write("ET\n");
        currentStream.write("Q\n");
    }

    /**
     * Applies the given alpha values for filling and stroking.
     * @param fillAlpha A value between 0 and 255 (=OPAQUE) for filling
     * @param strokeAlpha A value between 0 and 255 (=OPAQUE) for stroking
     */
    protected void applyAlpha(int fillAlpha, int strokeAlpha) {
        if (fillAlpha != OPAQUE || strokeAlpha != OPAQUE) {
            checkTransparencyAllowed();
            Map vals = new java.util.HashMap();
            if (fillAlpha != OPAQUE) {
                vals.put(PDFGState.GSTATE_ALPHA_NONSTROKE, new Float(fillAlpha / 255f));
            }
            if (strokeAlpha != OPAQUE) {
                vals.put(PDFGState.GSTATE_ALPHA_STROKE, new Float(strokeAlpha / 255f));
            }
            PDFGState gstate = pdfDoc.getFactory().makeGState(
                    vals, graphicsState.getGState());
            resourceContext.addGState(gstate);
            currentStream.write("/" + gstate.getName() + " gs\n");
        }
    }

    /**
     * Updates the currently selected font.
     * @param font the new font to use
     */
    protected void updateCurrentFont(Font font) {
        String name = font.getFontName();
        float size = (float)font.getFontSize() / 1000f;

        //Only update if necessary
        if ((!name.equals(this.currentFontName))
                || (size != this.currentFontSize)) {
            this.currentFontName = name;
            this.currentFontSize = size;
            currentStream.write("/" + name + " " + size + " Tf\n");
        }
    }

    /**
     * Returns a suitable internal font given an AWT Font instance.
     * @param awtFont the AWT font
     * @return the internal Font
     */
    protected Font getInternalFontForAWTFont(java.awt.Font awtFont) {
        Font fontState;
        String n = awtFont.getFamily();
        if (n.equals("sanserif")) {
            n = "sans-serif";
        }
        float siz = awtFont.getSize2D();
        String style = awtFont.isItalic() ? "italic" : "normal";
        int weight = awtFont.isBold() ? Font.WEIGHT_BOLD : Font.WEIGHT_NORMAL;
        FontTriplet triplet = fontInfo.fontLookup(n, style, weight);
        fontState = fontInfo.getFontInstance(triplet, (int)(siz * 1000 + 0.5));
        return fontState;
    }

    /**
     * Determines whether the font with the given name is a multi-byte font.
     * @param name the name of the font
     * @return true if it's a multi-byte font
     */
    protected boolean isMultiByteFont(String name) {
        // This assumes that *all* CIDFonts use a /ToUnicode mapping
        org.apache.fop.fonts.Typeface f
            = (org.apache.fop.fonts.Typeface)fontInfo.getFonts().get(name);
        return f.isMultiByte();
    }

    private void addKerning(StringWriter buf, Integer ch1, Integer ch2,
                            Map kerning, String startText,
                            String endText) {
        preparePainting();
        Map kernPair = (Map)kerning.get(ch1);

        if (kernPair != null) {
            Integer width = (Integer)kernPair.get(ch2);
            if (width != null) {
                currentStream.write(endText + (-width.intValue()) + " " + startText);
            }
        }
    }

    /**
     * Renders the text of the specified iterator, using the
     * <code>Graphics2D</code> context's current <code>Paint</code>. The
     * iterator must specify a font
     * for each character. The baseline of the
     * first character is at position (<i>x</i>,&nbsp;<i>y</i>) in the
     * User Space.
     * The rendering attributes applied include the <code>Clip</code>,
     * <code>Transform</code>, <code>Paint</code>, and
     * <code>Composite</code> attributes.
     * For characters in script systems such as Hebrew and Arabic,
     * the glyphs can be rendered from right to left, in which case the
     * coordinate supplied is the location of the leftmost character
     * on the baseline.
     * @param iterator the iterator whose text is to be rendered
     * @param x the coordinate where the iterator's text is to be
     * rendered
     * @param y the coordinate where the iterator's text is to be
     * rendered
     * @see #setPaint
     * @see java.awt.Graphics#setColor
     * @see #setTransform
     * @see #setComposite
     * @see #setClip
     */
    public void drawString(AttributedCharacterIterator iterator, float x,
                           float y) {
        preparePainting();

        Font fontState = null;

        Shape imclip = getClip();
        writeClip(imclip);
        Color c = getColor();
        applyColor(c, true);
        applyPaint(getPaint(), true);

        boolean fill = true;
        boolean stroke = false;
        if (true) {
            Stroke currentStroke = getStroke();
            stroke = true;
            applyStroke(currentStroke);
            applyColor(c, false);
            applyPaint(getPaint(), false);
        }

        currentStream.write("BT\n");

        // set text rendering mode:
        // 0 - fill, 1 - stroke, 2 - fill then stroke
        int textr = 0;
        if (fill && stroke) {
            textr = 2;
        } else if (stroke) {
            textr = 1;
        }
        currentStream.write(textr + " Tr\n");

        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();

            String name = fontState.getFontName();
            int size = fontState.getFontSize();
            if ((!name.equals(this.currentFontName))
                    || (size != this.currentFontSize)) {
                this.currentFontName = name;
                this.currentFontSize = size;
                currentStream.write("/" + name + " " + (size / 1000)
                                    + " Tf\n");

            }

            currentStream.write(PDFNumber.doubleOut(vals[0], DEC) + " "
                                + PDFNumber.doubleOut(vals[1], DEC) + " "
                                + PDFNumber.doubleOut(vals[2], DEC) + " "
                                + PDFNumber.doubleOut(vals[3], DEC) + " "
                                + PDFNumber.doubleOut(vals[4], DEC) + " "
                                + PDFNumber.doubleOut(vals[5], DEC) + " Tm (" + ch
                                + ") Tj\n");
        }

        currentStream.write("ET\n");
    }

    /**
     * Fills the interior of a <code>Shape</code> using the settings of the
     * <code>Graphics2D</code> context. The rendering attributes applied
     * include the <code>Clip</code>, <code>Transform</code>,
     * <code>Paint</code>, and <code>Composite</code>.
     * @param s the <code>Shape</code> to be filled
     * @see #setPaint
     * @see java.awt.Graphics#setColor
     * @see #transform
     * @see #setTransform
     * @see #setComposite
     * @see #clip
     * @see #setClip
     */
    public void fill(Shape s) {
        preparePainting();

        //Transparency shortcut
        Color c;
        c = getBackground();
        if (c.getAlpha() == 0) {
            c = getColor();
            if (c.getAlpha() == 0) {
                return;
            }
        }
        
        AffineTransform trans = getTransform();
        double[] tranvals = new double[6];
        trans.getMatrix(tranvals);

        Shape imclip = getClip();
        boolean newClip = graphicsState.checkClip(imclip);
        boolean newTransform = graphicsState.checkTransform(trans)
                               && !trans.isIdentity();

        if (newClip || newTransform) {
            currentStream.write("q\n");
            graphicsState.push();
            if (newTransform) {
                concatMatrix(tranvals);
            }
            if (newClip) {
                writeClip(imclip);
            }
        }

        applyAlpha(c.getAlpha(), OPAQUE);

        c = getColor();
        applyColor(c, true);
        c = getBackground();
        applyColor(c, false);

        Paint paint = getPaint();
        if (graphicsState.setPaint(paint)) {
            if (!applyPaint(paint, true)) {
                // Use the shape to 'clip' the paint contents.
                applyUnknownPaint(paint, s);

                if (newClip || newTransform) {
                    currentStream.write("Q\n");
                    graphicsState.pop();
                }
                return;
            }
        }

        //PathIterator iter = s.getPathIterator(getTransform());
        PathIterator iter = s.getPathIterator(IDENTITY_TRANSFORM);
        processPathIterator(iter);
        doDrawing(true, false,
                  iter.getWindingRule() == PathIterator.WIND_EVEN_ODD);
        if (newClip || newTransform) {
            currentStream.write("Q\n");
            graphicsState.pop();
        }
    }

    /** Checks whether the use of transparency is allowed. */
    protected void checkTransparencyAllowed() {
        pdfDoc.getProfile().verifyTransparencyAllowed("Java2D graphics");
    }

    /**
     * Processes a path iterator generating the necessary painting operations.
     * @param iter PathIterator to process
     */
    public void processPathIterator(PathIterator iter) {
        while (!iter.isDone()) {
            double[] vals = new double[6];
            int type = iter.currentSegment(vals);
            switch (type) {
            case PathIterator.SEG_CUBICTO:
                currentStream.write(PDFNumber.doubleOut(vals[0], DEC) + " "
                                    + PDFNumber.doubleOut(vals[1], DEC) + " "
                                    + PDFNumber.doubleOut(vals[2], DEC) + " "
                                    + PDFNumber.doubleOut(vals[3], DEC) + " "
                                    + PDFNumber.doubleOut(vals[4], DEC) + " "
                                    + PDFNumber.doubleOut(vals[5], DEC) + " c\n");
                break;
            case PathIterator.SEG_LINETO:
                currentStream.write(PDFNumber.doubleOut(vals[0], DEC) + " "
                                    + PDFNumber.doubleOut(vals[1], DEC) + " l\n");
                break;
            case PathIterator.SEG_MOVETO:
                currentStream.write(PDFNumber.doubleOut(vals[0], DEC) + " "
                                    + PDFNumber.doubleOut(vals[1], DEC) + " m\n");
                break;
            case PathIterator.SEG_QUADTO:
                currentStream.write(PDFNumber.doubleOut(vals[0], DEC) + " "
                                    + PDFNumber.doubleOut(vals[1], DEC) + " "
                                    + PDFNumber.doubleOut(vals[2], DEC) + " "
                                    + PDFNumber.doubleOut(vals[3], DEC) + " y\n");
                break;
            case PathIterator.SEG_CLOSE:
                currentStream.write("h\n");
                break;
            default:
                break;
            }
            iter.next();
        }
    }
    
    /**
     * Do the PDF drawing command.
     * This does the PDF drawing command according to fill
     * stroke and winding rule.
     *
     * @param fill true if filling the path
     * @param stroke true if stroking the path
     * @param nonzero true if using the non-zero winding rule
     */
    protected void doDrawing(boolean fill, boolean stroke, boolean nonzero) {
        preparePainting();
        if (fill) {
            if (stroke) {
                if (nonzero) {
                    currentStream.write("B*\n");
                } else {
                    currentStream.write("B\n");
                }
            } else {
                if (nonzero) {
                    currentStream.write("f*\n");
                } else {
                    currentStream.write("f\n");
                }
            }
        } else {
            // if (stroke)
            currentStream.write("S\n");
        }
    }

    /**
     * Returns the device configuration associated with this
     * <code>Graphics2D</code>.
     *
     * @return the PDF graphics configuration
     */
    public GraphicsConfiguration getDeviceConfiguration() {
        return new PDFGraphicsConfiguration();
    }

    /**
     * Used to create proper font metrics
     */
    private Graphics2D fmg;

    {
        BufferedImage bi = new BufferedImage(1, 1,
                                             BufferedImage.TYPE_INT_ARGB);

        fmg = bi.createGraphics();
    }

    /**
     * Gets the font metrics for the specified font.
     * @return    the font metrics for the specified font.
     * @param     f the specified font
     * @see       java.awt.Graphics#getFont
     * @see       java.awt.FontMetrics
     * @see       java.awt.Graphics#getFontMetrics()
     */
    public java.awt.FontMetrics getFontMetrics(java.awt.Font f) {
        return fmg.getFontMetrics(f);
    }

    /**
     * Sets the paint mode of this graphics context to alternate between
     * this graphics context's current color and the new specified color.
     * This specifies that logical pixel operations are performed in the
     * XOR mode, which alternates pixels between the current color and
     * a specified XOR color.
     * <p>
     * When drawing operations are performed, pixels which are the
     * current color are changed to the specified color, and vice versa.
     * <p>
     * Pixels that are of colors other than those two colors are changed
     * in an unpredictable but reversible manner; if the same figure is
     * drawn twice, then all pixels are restored to their original values.
     * @param     c1 the XOR alternation color
     */
    public void setXORMode(Color c1) {
        //NYI
    }


    /**
     * Copies an area of the component by a distance specified by
     * <code>dx</code> and <code>dy</code>. From the point specified
     * by <code>x</code> and <code>y</code>, this method
     * copies downwards and to the right.  To copy an area of the
     * component to the left or upwards, specify a negative value for
     * <code>dx</code> or <code>dy</code>.
     * If a portion of the source rectangle lies outside the bounds
     * of the component, or is obscured by another window or component,
     * <code>copyArea</code> will be unable to copy the associated
     * pixels. The area that is omitted can be refreshed by calling
     * the component's <code>paint</code> method.
     * @param       x the <i>x</i> coordinate of the source rectangle.
     * @param       y the <i>y</i> coordinate of the source rectangle.
     * @param       width the width of the source rectangle.
     * @param       height the height of the source rectangle.
     * @param       dx the horizontal distance to copy the pixels.
     * @param       dy the vertical distance to copy the pixels.
     */
    public void copyArea(int x, int y, int width, int height, int dx,
                         int dy) {
        //NYI
    }

}
