/*
 * 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.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.util.ArrayList;
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.GraphicsConstants;
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.xmlgraphics.java2d.GraphicsConfigurationWithTransparency;

import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontSetup;
import org.apache.fop.pdf.BitmapImage;
import org.apache.fop.pdf.PDFAnnotList;
import org.apache.fop.pdf.PDFColor;
import org.apache.fop.pdf.PDFColorHandler;
import org.apache.fop.pdf.PDFConformanceException;
import org.apache.fop.pdf.PDFDeviceColorSpace;
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFFunction;
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.PDFPaintingState;
import org.apache.fop.pdf.PDFPattern;
import org.apache.fop.pdf.PDFResourceContext;
import org.apache.fop.pdf.PDFResources;
import org.apache.fop.pdf.PDFShading;
import org.apache.fop.pdf.PDFText;
import org.apache.fop.pdf.PDFXObject;
import org.apache.fop.render.gradient.Function;
import org.apache.fop.render.gradient.GradientMaker;
import org.apache.fop.render.gradient.Pattern;
import org.apache.fop.render.gradient.Shading;
import org.apache.fop.render.pdf.ImageRawCCITTFaxAdapter;
import org.apache.fop.render.pdf.ImageRawJPEGAdapter;
import org.apache.fop.render.pdf.ImageRenderedAdapter;

/**
 * <p>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.</p>
 *
 * <p>This work was authored by Keiron Liddle (keiron@aftexsw.com).</p>
 *
 * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D
 */
public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHandler {
    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 PDF painting state
     */
    protected PDFPaintingState paintingState;

    /** the PDF color handler */
    protected PDFColorHandler colorHandler;

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

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

    /**
     * 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;

    /**
     * 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;

    private TransparencyIgnoredEventListener transparencyIgnoredEventListener;

    /**
     * May be used to give proper feedback to the user when a particular PDF profile is
     * being used that disallows transparency.
     */
    public interface TransparencyIgnoredEventListener {

        void transparencyIgnored(Object pdfProfile);
    }

    /**
     * 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,
                         TransparencyIgnoredEventListener listener) {
        this(textAsShapes);
        pdfDoc = doc;
        this.colorHandler = new PDFColorHandler(doc.getResources());
        resourceContext = page;
        currentFontName = font;
        currentFontSize = size;
        fontInfo = fi;
        pageRef = pref;
        paintingState = new PDFPaintingState();
        this.transparencyIgnoredEventListener = listener;
    }

    /**
     * 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.colorHandler = g.colorHandler;
        this.resourceContext = g.resourceContext;
        this.currentFontName = g.currentFontName;
        this.currentFontSize = g.currentFontSize;
        this.fontInfo = g.fontInfo;
        this.pageRef = g.pageRef;
        this.paintingState = g.paintingState;
        this.currentStream = g.currentStream;
        this.nativeCount = g.nativeCount;
        this.outputStream = g.outputStream;
        this.ovFontState = g.ovFontState;
        this.transparencyIgnoredEventListener = g.transparencyIgnoredEventListener;
    }

    /**
     * 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.
     */
    @Override
    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 setPaintingState(PDFPaintingState state) {
        paintingState = state;
        baseLevel = paintingState.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
     * Graphics.
     * @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 Graphics so far.
     * @return the StringBuffer containing the PDF markup
     */
    public StringBuffer getBuffer() {
        return currentStream.getBuffer();
    }

    /**
     * Gets the PDF reference of the current page.
     * @return the PDF reference of the current page
     */
    public String getPageReference() {
        return this.pageRef;
    }

    /**
     * Set the Graphics 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(paintingState.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, getPageReference(), 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
     */
    public 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);
        flushPDFDocument();

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

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

    /**
     * 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)
     */
    @Override
    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} */
    @Override
    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);

            int imageWidth = buf.getWidth();
            int imageHeight = buf.getHeight();
            g.clip(new Rectangle(0, 0, imageWidth, imageHeight));
            g.setComposite(gc.getComposite());

            boolean drawn = g.drawImage(img, 0, 0, imageWidth, imageHeight, observer);
            if (!drawn) {
                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
     */
    @Override
    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
     */
    @Override
    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 = paintingState.checkClip(imclip);
        boolean newTransform = paintingState.checkTransform(trans)
                               && !trans.isIdentity();

        if (newClip || newTransform) {
            saveGraphicsState();
            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 (paintingState.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) {
                    restoreGraphicsState();
                }
                return;
            }
        }
        applyStroke(getStroke());

        PathIterator iter = s.getPathIterator(IDENTITY_TRANSFORM);
        processPathIterator(iter);
        doDrawing(false, true, false);
        if (newClip || newTransform) {
            restoreGraphicsState();
        }
    }

/*
    // 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;
        }
        PathIterator iter = s.getPathIterator(IDENTITY_TRANSFORM);
        if (iter.isDone()) {
            // no segments available. Not worth doing anything
            return;
        }
        preparePainting();

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

        //TODO Handle this in PDFColorHandler by automatically converting the color.
        //This won't work properly anyway after the redesign of ColorExt
        if (col.getColorSpace().getType() == ColorSpace.TYPE_CMYK) {
             if (pdfDoc.getProfile().getPDFAMode().isPart1()) {
                 //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.");
             }
        }

        boolean doWrite = false;
        if (fill) {
            if (paintingState.setBackColor(col)) {
                doWrite = true;
            }
        } else {
            if (paintingState.setColor(col)) {
                doWrite = true;
            }
        }
        if (doWrite) {
            StringBuffer sb = new StringBuffer();
            colorHandler.establishColor(sb, col, fill);
            currentStream.write(sb.toString());
        }
    }

    /**
     * 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 && gradientSupported((LinearGradientPaint) paint)) {
            Pattern pattern = GradientMaker.makeLinearGradient((LinearGradientPaint) paint,
                    getBaseTransform(), getTransform());
            PDFPattern pdfPattern = createPDFPattern(pattern);
            currentStream.write(pdfPattern.getColorSpaceOut(fill));
            return true;
        }
        if (paint instanceof RadialGradientPaint && gradientSupported((RadialGradientPaint) paint)) {
            Pattern pattern = GradientMaker.makeRadialGradient((RadialGradientPaint) paint,
                    getBaseTransform(), getTransform());
            PDFPattern pdfPattern = createPDFPattern(pattern);
            currentStream.write(pdfPattern.getColorSpaceOut(fill));
            return true;
        }
        if (paint instanceof PatternPaint) {
            PatternPaint pp = (PatternPaint)paint;
            return createPattern(pp, fill);
        }
        return false; // unknown paint
    }

    private PDFPattern createPDFPattern(Pattern pattern) {
        Shading shading = pattern.getShading();
        Function function = shading.getFunction();
        List<PDFFunction> pdfFunctions = new ArrayList<PDFFunction>(function.getFunctions().size());
        for (Function f : function.getFunctions()) {
            pdfFunctions.add(registerFunction(new PDFFunction(f)));
        }
        PDFFunction pdfFunction = registerFunction(new PDFFunction(function, pdfFunctions));
        PDFShading pdfShading = new PDFShading(shading.getShadingType(), shading.getColorSpace(), shading.getCoords(),
                pdfFunction);
        pdfShading = registerShading(pdfShading);
        PDFPattern pdfPattern = new PDFPattern(pattern.getPatternType(), pdfShading, null, null, pattern.getMatrix());
        return registerPattern(pdfPattern);
    }

    private boolean gradientSupported(MultipleGradientPaint gradient) {
        return !(gradientContainsTransparency(gradient) || gradientIsRepeated(gradient));
    }

    private boolean gradientContainsTransparency(MultipleGradientPaint gradient) {
        for (Color color : gradient.getColors()) {
            if (color.getAlpha() != 255) {
                return true;
            }
        }
        return false;
    }

    private boolean gradientIsRepeated(MultipleGradientPaint gradient) {
         // For linear gradients it is possible to construct a 'tile' that is repeated with
         // a PDF pattern, but it would be very tricky as the coordinate system would have
         // to be rotated so the repeat is axially aligned.

         // For radial gradients there is essentially no way to support repeats in PDF (the
         // one option would be to 'grow' the outer circle until it fully covers 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).
        return (gradient.getCycleMethod() != MultipleGradientPaint.NO_CYCLE);
    }

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

        FontInfo specialFontInfo = new FontInfo();
        boolean base14Kerning = false;
        FontSetup.setup(specialFontInfo, base14Kerning);

        PDFResources res = pdfDoc.getFactory().makeResources();
        PDFResourceContext context = new PDFResourceContext(res);
        PDFGraphics2D pattGraphic = new PDFGraphics2D(textAsShapes, specialFontInfo,
                                        pdfDoc, context, getPageReference(),
                                        "", 0, transparencyIgnoredEventListener);
        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<Double> bbox = new java.util.ArrayList<Double>();
        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<Double> theMatrix = new java.util.ArrayList<Double>();
        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);
        }

        flushPDFDocument();
        return true;
    }

    /**
     * @param paint some paint
     * @param shape a shape
     * @return true (always)
     */
    protected boolean applyUnknownPaint(Paint paint, Shape shape) {
        preparePainting();

        Shape clip = getClip();
        Rectangle2D usrClipBounds;
        Rectangle2D 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;
        Rectangle devClipBounds;
        Rectangle 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;
            int y;
            int val;
            int 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();

                flushPDFDocument();
            }
            BitmapImage fopimg;
            fopimg = new BitmapImage("TempImage:" + pctx.toString(),
                                     devW, devH, rgb, maskRef);
            fopimg.setTransparent(new PDFColor(255, 255, 255));
            imageInfo = pdfDoc.addImage(resourceContext, fopimg);
            flushPDFDocument();
        }

        currentStream.write("q\n");
        writeClip(shape);
        currentStream.write("" + PDFNumber.doubleOut(usrW) + " 0 0 " + PDFNumber.doubleOut(-usrH) + " "
                + PDFNumber.doubleOut(usrX) + " " + PDFNumber.doubleOut(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");
            } else {
                currentStream.write("[] 0 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;
            default:
                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;
            default:
                break;
            }
            float lw = bs.getLineWidth();
            currentStream.write(PDFNumber.doubleOut(lw) + " w\n");

            float ml = Math.max(1.0f, bs.getMiterLimit());
            currentStream.write(PDFNumber.doubleOut(ml) + " M\n");
        }
    }

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

    /**
     * @param key a key
     * @param img an image
     * @param xform a transform
     */
    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(),
                GraphicsConstants.DEFAULT_DPI);
        info.setSize(size);
        ImageRendered imgRend = new ImageRendered(info, img, null);
        ImageRenderedAdapter adapter = new ImageRenderedAdapter(imgRend, key);
        PDFXObject xObject = pdfDoc.addImage(resourceContext, adapter);
        flushPDFDocument();
        return xObject;
    }

    /** {@inheritDoc} */
    @Override
    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
     */
    @Override
    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 = fontInfo.getFontInstanceForAWTFont(gFont);
        } else {
            fontState = fontInfo.getFontInstance(
                    ovFontState.getFontTriplet(), ovFontState.getFontSize());
            ovFontState = null;
        }
        updateCurrentFont(fontState);

        saveGraphicsState();

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

        Map<Integer, Map<Integer, Integer>> 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(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, (Integer.valueOf(ch)),
                           (Integer.valueOf(fontState.mapChar(s.charAt(i + 1)))),
                           kerning, startText, endText);
            }

        }
        currentStream.write(endText);

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

    /**
     * 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) {
            Object profile = isTransparencyAllowed();
            if (profile == null) {
                Map<String, Float> vals = new java.util.HashMap<String, Float>();
                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, paintingState.getGState());
                resourceContext.addGState(gstate);
                currentStream.write("/" + gstate.getName() + " gs\n");
            } else if (transparencyIgnoredEventListener != null) {
                transparencyIgnoredEventListener.transparencyIgnored(profile);
            }
        }
    }

    /**
     * Updates the currently selected font.
     * @param font the new font to use
     */
    protected void updateCurrentFont(Font font) {
        String name = font.getFontName();
        float size = 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
     * @deprecated use FontInfo.getFontInstanceForAWTFont(java.awt.Font awtFont) instead
     */
    @Deprecated
    protected Font getInternalFontForAWTFont(java.awt.Font awtFont) {
        return fontInfo.getFontInstanceForAWTFont(awtFont);
    }

    /**
     * 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
            = fontInfo.getFonts().get(name);
        return f.isMultiByte();
    }

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

        if (kernPair != null) {
            Integer width = 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
     *//* TODO Reimplement for higher efficiency similar to the way it was done in PDFTextPainter
    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
     */
    @Override
    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 = paintingState.checkClip(imclip);
        boolean newTransform = paintingState.checkTransform(trans)
                               && !trans.isIdentity();

        if (newClip || newTransform) {
            saveGraphicsState();
            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 (paintingState.setPaint(paint)) {
            if (!applyPaint(paint, true)) {
                // Use the shape to 'clip' the paint contents.
                applyUnknownPaint(paint, s);

                if (newClip || newTransform) {
                    restoreGraphicsState();
                }
                return;
            }
        }

        if (s instanceof Rectangle2D) {
            Rectangle2D rect = (Rectangle2D)s;
            currentStream.write(PDFNumber.doubleOut(rect.getMinX(), DEC) + " "
                    + PDFNumber.doubleOut(rect.getMinY(), DEC) + " ");
            currentStream.write(PDFNumber.doubleOut(rect.getWidth(), DEC) + " "
                    + PDFNumber.doubleOut(rect.getHeight(), DEC) + " re ");
            doDrawing(true, false, false);
        } else {
            PathIterator iter = s.getPathIterator(IDENTITY_TRANSFORM);
            processPathIterator(iter);
            doDrawing(true, false,
                    iter.getWindingRule() == PathIterator.WIND_EVEN_ODD);
        }
        if (newClip || newTransform) {
            restoreGraphicsState();
        }
    }

    void saveGraphicsState() {
        currentStream.write("q\n");
        paintingState.save();
    }

    void restoreGraphicsState() {
        currentStream.write("Q\n");
        paintingState.restore();
    }

    /** Checks whether the use of transparency is allowed. */
    protected Object isTransparencyAllowed() {
        return pdfDoc.getProfile().isTransparencyAllowed();
    }

    /**
     * Processes a path iterator generating the necessary painting operations.
     * @param iter PathIterator to process
     */
    public void processPathIterator(PathIterator iter) {
        double lastX = 0.0;
        double lastY = 0.0;
        while (!iter.isDone()) {
            double[] vals = new double[6];
            int type = iter.currentSegment(vals);
            switch (type) {
            case PathIterator.SEG_CUBICTO:
                lastX = vals[4];
                lastY = vals[5];
                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:
                lastX = vals[0];
                lastY = vals[1];
                currentStream.write(PDFNumber.doubleOut(vals[0], DEC) + " "
                                    + PDFNumber.doubleOut(vals[1], DEC) + " l\n");
                break;
            case PathIterator.SEG_MOVETO:
                lastX = vals[0];
                lastY = vals[1];
                currentStream.write(PDFNumber.doubleOut(vals[0], DEC) + " "
                                    + PDFNumber.doubleOut(vals[1], DEC) + " m\n");
                break;
            case PathIterator.SEG_QUADTO:
                double controlPointAX = lastX + ((2.0 / 3.0) * (vals[0] - lastX));
                double controlPointAY = lastY + ((2.0 / 3.0) * (vals[1] - lastY));
                double controlPointBX = vals[2] + ((2.0 / 3.0) * (vals[0] - vals[2]));
                double controlPointBY = vals[3] + ((2.0 / 3.0) * (vals[1] - vals[3]));
                currentStream.write(PDFNumber.doubleOut(controlPointAX, DEC) + " "
                        + PDFNumber.doubleOut(controlPointAY, DEC) + " "
                        + PDFNumber.doubleOut(controlPointBX, DEC) + " "
                        + PDFNumber.doubleOut(controlPointBY, DEC) + " "
                        + PDFNumber.doubleOut(vals[2], DEC) + " "
                        + PDFNumber.doubleOut(vals[3], DEC) + " c\n");
                lastX = vals[2];
                lastY = vals[3];
                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
     */
    @Override
    public GraphicsConfiguration getDeviceConfiguration() {
        return new GraphicsConfigurationWithTransparency();
    }

    /**
     * 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()
     */
    @Override
    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
     */
    @Override
    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.
     */
    @Override
    public void copyArea(int x, int y, int width, int height, int dx,
                         int dy) {
        //NYI
    }

    /**
     * Registers a function object against the output format document
     * @param function The function object to register
     * @return Returns either the function which has already been registered
     * or the current new registered object.
     */
    public PDFFunction registerFunction(PDFFunction function) {
        return pdfDoc.getFactory().registerFunction(function);
    }

    /**
     * Registers a shading object against the otuput format document
     * @param shading The shading object to register
     * @return Returs either the shading which has already been registered
     * or the current new registered object
     */
    public PDFShading registerShading(PDFShading shading) {
        return pdfDoc.getFactory().registerShading(resourceContext, shading);
    }

    /**
     * Registers a pattern object against the output format document
     * @param pattern The pattern object to register
     * @return Returns either the pattern which has already been registered
     * or the current new registered object
     */
    public PDFPattern registerPattern(PDFPattern pattern) {
        return pdfDoc.getFactory().registerPattern(resourceContext, pattern);
    }

}
