/*
 * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.print;

import java.lang.ref.SoftReference;
import java.util.Hashtable;
import sun.font.CharToGlyphMapper;
import sun.font.CompositeFont;
import sun.font.Font2D;
import sun.font.Font2DHandle;
import sun.font.FontManager;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Paint;
import java.awt.Polygon;
import java.awt.Shape;

import java.text.AttributedCharacterIterator;

import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;

import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.geom.PathIterator;

import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferInt;
import java.awt.image.ImageObserver;
import java.awt.image.IndexColorModel;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.awt.image.SampleModel;
import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.VolatileImage;
import sun.awt.image.ByteComponentRaster;
import sun.awt.image.ToolkitImage;
import sun.awt.image.SunWritableRaster;

import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterGraphics;
import java.awt.print.PrinterJob;

import java.util.Map;

public abstract class PathGraphics extends ProxyGraphics2D {

    private Printable mPainter;
    private PageFormat mPageFormat;
    private int mPageIndex;
    private boolean mCanRedraw;
    protected boolean printingGlyphVector;

    protected PathGraphics(Graphics2D graphics, PrinterJob printerJob,
                           Printable painter, PageFormat pageFormat,
                           int pageIndex, boolean canRedraw) {
        super(graphics, printerJob);

        mPainter = painter;
        mPageFormat = pageFormat;
        mPageIndex = pageIndex;
        mCanRedraw = canRedraw;
    }

    /**
     * Return the Printable instance responsible for drawing
     * into this Graphics.
     */
    protected Printable getPrintable() {
        return mPainter;
    }

    /**
     * Return the PageFormat associated with this page of
     * Graphics.
     */
    protected PageFormat getPageFormat() {
        return mPageFormat;
    }

    /**
     * Return the page index associated with this Graphics.
     */
    protected int getPageIndex() {
        return mPageIndex;
    }

    /**
     * Return true if we are allowed to ask the application
     * to redraw portions of the page. In general, with the
     * PrinterJob API, the application can be asked to do a
     * redraw. When PrinterJob is emulating PrintJob then we
     * can not.
     */
    public boolean canDoRedraws() {
        return mCanRedraw;
    }

     /**
      * Redraw a rectanglular area using a proxy graphics
      */
    public abstract void redrawRegion(Rectangle2D region,
                                      double scaleX, double scaleY,
                                      Shape clip,
                                      AffineTransform devTransform)

                    throws PrinterException ;

    /**
     * Draws a line, using the current color, between the points
     * <code>(x1,&nbsp;y1)</code> and <code>(x2,&nbsp;y2)</code>
     * in this graphics context's coordinate system.
     * @param   x1  the first point's <i>x</i> coordinate.
     * @param   y1  the first point's <i>y</i> coordinate.
     * @param   x2  the second point's <i>x</i> coordinate.
     * @param   y2  the second point's <i>y</i> coordinate.
     */
    public void drawLine(int x1, int y1, int x2, int y2) {

        Paint paint = getPaint();

        try {
            AffineTransform deviceTransform = getTransform();
            if (getClip() != null) {
                deviceClip(getClip().getPathIterator(deviceTransform));
            }

            deviceDrawLine(x1, y1, x2, y2, (Color) paint);

        } catch (ClassCastException e) {
            throw new IllegalArgumentException("Expected a Color instance");
        }
    }


    /**
     * Draws the outline of the specified rectangle.
     * The left and right edges of the rectangle are at
     * <code>x</code> and <code>x&nbsp;+&nbsp;width</code>.
     * The top and bottom edges are at
     * <code>y</code> and <code>y&nbsp;+&nbsp;height</code>.
     * The rectangle is drawn using the graphics context's current color.
     * @param         x   the <i>x</i> coordinate
     *                         of the rectangle to be drawn.
     * @param         y   the <i>y</i> coordinate
     *                         of the rectangle to be drawn.
     * @param         width   the width of the rectangle to be drawn.
     * @param         height   the height of the rectangle to be drawn.
     * @see          java.awt.Graphics#fillRect
     * @see          java.awt.Graphics#clearRect
     */
    public void drawRect(int x, int y, int width, int height) {

        Paint paint = getPaint();

        try {
            AffineTransform deviceTransform = getTransform();
            if (getClip() != null) {
                deviceClip(getClip().getPathIterator(deviceTransform));
            }

            deviceFrameRect(x, y, width, height, (Color) paint);

        } catch (ClassCastException e) {
            throw new IllegalArgumentException("Expected a Color instance");
        }

    }

    /**
     * Fills the specified rectangle.
     * The left and right edges of the rectangle are at
     * <code>x</code> and <code>x&nbsp;+&nbsp;width&nbsp;-&nbsp;1</code>.
     * The top and bottom edges are at
     * <code>y</code> and <code>y&nbsp;+&nbsp;height&nbsp;-&nbsp;1</code>.
     * The resulting rectangle covers an area
     * <code>width</code> pixels wide by
     * <code>height</code> pixels tall.
     * The rectangle is filled using the graphics context's current color.
     * @param         x   the <i>x</i> coordinate
     *                         of the rectangle to be filled.
     * @param         y   the <i>y</i> coordinate
     *                         of the rectangle to be filled.
     * @param         width   the width of the rectangle to be filled.
     * @param         height   the height of the rectangle to be filled.
     * @see           java.awt.Graphics#clearRect
     * @see           java.awt.Graphics#drawRect
     */
    public void fillRect(int x, int y, int width, int height){

        Paint paint = getPaint();

        try {
            AffineTransform deviceTransform = getTransform();
            if (getClip() != null) {
                deviceClip(getClip().getPathIterator(deviceTransform));
            }

            deviceFillRect(x, y, width, height, (Color) paint);

        } catch (ClassCastException e) {
            throw new IllegalArgumentException("Expected a Color instance");
        }
    }

       /**
     * Clears the specified rectangle by filling it with the background
     * color of the current drawing surface. This operation does not
     * use the current paint mode.
     * <p>
     * Beginning with Java&nbsp;1.1, the background color
     * of offscreen images may be system dependent. Applications should
     * use <code>setColor</code> followed by <code>fillRect</code> to
     * ensure that an offscreen image is cleared to a specific color.
     * @param       x the <i>x</i> coordinate of the rectangle to clear.
     * @param       y the <i>y</i> coordinate of the rectangle to clear.
     * @param       width the width of the rectangle to clear.
     * @param       height the height of the rectangle to clear.
     * @see         java.awt.Graphics#fillRect(int, int, int, int)
     * @see         java.awt.Graphics#drawRect
     * @see         java.awt.Graphics#setColor(java.awt.Color)
     * @see         java.awt.Graphics#setPaintMode
     * @see         java.awt.Graphics#setXORMode(java.awt.Color)
     */
    public void clearRect(int x, int y, int width, int height) {

        fill(new Rectangle2D.Float(x, y, width, height), getBackground());
    }

        /**
     * Draws an outlined round-cornered rectangle using this graphics
     * context's current color. The left and right edges of the rectangle
     * are at <code>x</code> and <code>x&nbsp;+&nbsp;width</code>,
     * respectively. The top and bottom edges of the rectangle are at
     * <code>y</code> and <code>y&nbsp;+&nbsp;height</code>.
     * @param      x the <i>x</i> coordinate of the rectangle to be drawn.
     * @param      y the <i>y</i> coordinate of the rectangle to be drawn.
     * @param      width the width of the rectangle to be drawn.
     * @param      height the height of the rectangle to be drawn.
     * @param      arcWidth the horizontal diameter of the arc
     *                    at the four corners.
     * @param      arcHeight the vertical diameter of the arc
     *                    at the four corners.
     * @see        java.awt.Graphics#fillRoundRect
     */
    public void drawRoundRect(int x, int y, int width, int height,
                              int arcWidth, int arcHeight) {

        draw(new RoundRectangle2D.Float(x, y,
                                        width, height,
                                        arcWidth, arcHeight));
    }


    /**
     * Fills the specified rounded corner rectangle with the current color.
     * The left and right edges of the rectangle
     * are at <code>x</code> and <code>x&nbsp;+&nbsp;width&nbsp;-&nbsp;1</code>,
     * respectively. The top and bottom edges of the rectangle are at
     * <code>y</code> and <code>y&nbsp;+&nbsp;height&nbsp;-&nbsp;1</code>.
     * @param       x the <i>x</i> coordinate of the rectangle to be filled.
     * @param       y the <i>y</i> coordinate of the rectangle to be filled.
     * @param       width the width of the rectangle to be filled.
     * @param       height the height of the rectangle to be filled.
     * @param       arcWidth the horizontal diameter
     *                     of the arc at the four corners.
     * @param       arcHeight the vertical diameter
     *                     of the arc at the four corners.
     * @see         java.awt.Graphics#drawRoundRect
     */
    public void fillRoundRect(int x, int y, int width, int height,
                              int arcWidth, int arcHeight) {

        fill(new RoundRectangle2D.Float(x, y,
                                        width, height,
                                        arcWidth, arcHeight));
    }

    /**
     * Draws the outline of an oval.
     * The result is a circle or ellipse that fits within the
     * rectangle specified by the <code>x</code>, <code>y</code>,
     * <code>width</code>, and <code>height</code> arguments.
     * <p>
     * The oval covers an area that is
     * <code>width&nbsp;+&nbsp;1</code> pixels wide
     * and <code>height&nbsp;+&nbsp;1</code> pixels tall.
     * @param       x the <i>x</i> coordinate of the upper left
     *                     corner of the oval to be drawn.
     * @param       y the <i>y</i> coordinate of the upper left
     *                     corner of the oval to be drawn.
     * @param       width the width of the oval to be drawn.
     * @param       height the height of the oval to be drawn.
     * @see         java.awt.Graphics#fillOval
     * @since       JDK1.0
     */
    public void drawOval(int x, int y, int width, int height) {
        draw(new Ellipse2D.Float(x, y, width, height));
    }

        /**
     * Fills an oval bounded by the specified rectangle with the
     * current color.
     * @param       x the <i>x</i> coordinate of the upper left corner
     *                     of the oval to be filled.
     * @param       y the <i>y</i> coordinate of the upper left corner
     *                     of the oval to be filled.
     * @param       width the width of the oval to be filled.
     * @param       height the height of the oval to be filled.
     * @see         java.awt.Graphics#drawOval
     */
    public void fillOval(int x, int y, int width, int height){

        fill(new Ellipse2D.Float(x, y, width, height));
    }

    /**
     * Draws the outline of a circular or elliptical arc
     * covering the specified rectangle.
     * <p>
     * The resulting arc begins at <code>startAngle</code> and extends
     * for <code>arcAngle</code> degrees, using the current color.
     * Angles are interpreted such that 0&nbsp;degrees
     * is at the 3&nbsp;o'clock position.
     * A positive value indicates a counter-clockwise rotation
     * while a negative value indicates a clockwise rotation.
     * <p>
     * The center of the arc is the center of the rectangle whose origin
     * is (<i>x</i>,&nbsp;<i>y</i>) and whose size is specified by the
     * <code>width</code> and <code>height</code> arguments.
     * <p>
     * The resulting arc covers an area
     * <code>width&nbsp;+&nbsp;1</code> pixels wide
     * by <code>height&nbsp;+&nbsp;1</code> pixels tall.
     * <p>
     * The angles are specified relative to the non-square extents of
     * the bounding rectangle such that 45 degrees always falls on the
     * line from the center of the ellipse to the upper right corner of
     * the bounding rectangle. As a result, if the bounding rectangle is
     * noticeably longer in one axis than the other, the angles to the
     * start and end of the arc segment will be skewed farther along the
     * longer axis of the bounds.
     * @param        x the <i>x</i> coordinate of the
     *                    upper-left corner of the arc to be drawn.
     * @param        y the <i>y</i>  coordinate of the
     *                    upper-left corner of the arc to be drawn.
     * @param        width the width of the arc to be drawn.
     * @param        height the height of the arc to be drawn.
     * @param        startAngle the beginning angle.
     * @param        arcAngle the angular extent of the arc,
     *                    relative to the start angle.
     * @see         java.awt.Graphics#fillArc
     */
    public void drawArc(int x, int y, int width, int height,
                                 int startAngle, int arcAngle) {
        draw(new Arc2D.Float(x, y, width, height,
                             startAngle, arcAngle,
                             Arc2D.OPEN));
    }


    /**
     * Fills a circular or elliptical arc covering the specified rectangle.
     * <p>
     * The resulting arc begins at <code>startAngle</code> and extends
     * for <code>arcAngle</code> degrees.
     * Angles are interpreted such that 0&nbsp;degrees
     * is at the 3&nbsp;o'clock position.
     * A positive value indicates a counter-clockwise rotation
     * while a negative value indicates a clockwise rotation.
     * <p>
     * The center of the arc is the center of the rectangle whose origin
     * is (<i>x</i>,&nbsp;<i>y</i>) and whose size is specified by the
     * <code>width</code> and <code>height</code> arguments.
     * <p>
     * The resulting arc covers an area
     * <code>width&nbsp;+&nbsp;1</code> pixels wide
     * by <code>height&nbsp;+&nbsp;1</code> pixels tall.
     * <p>
     * The angles are specified relative to the non-square extents of
     * the bounding rectangle such that 45 degrees always falls on the
     * line from the center of the ellipse to the upper right corner of
     * the bounding rectangle. As a result, if the bounding rectangle is
     * noticeably longer in one axis than the other, the angles to the
     * start and end of the arc segment will be skewed farther along the
     * longer axis of the bounds.
     * @param        x the <i>x</i> coordinate of the
     *                    upper-left corner of the arc to be filled.
     * @param        y the <i>y</i>  coordinate of the
     *                    upper-left corner of the arc to be filled.
     * @param        width the width of the arc to be filled.
     * @param        height the height of the arc to be filled.
     * @param        startAngle the beginning angle.
     * @param        arcAngle the angular extent of the arc,
     *                    relative to the start angle.
     * @see         java.awt.Graphics#drawArc
     */
    public void fillArc(int x, int y, int width, int height,
                                 int startAngle, int arcAngle) {

        fill(new Arc2D.Float(x, y, width, height,
                             startAngle, arcAngle,
                             Arc2D.PIE));
    }

    /**
     * Draws a sequence of connected lines defined by
     * arrays of <i>x</i> and <i>y</i> coordinates.
     * Each pair of (<i>x</i>,&nbsp;<i>y</i>) coordinates defines a point.
     * The figure is not closed if the first point
     * differs from the last point.
     * @param       xPoints an array of <i>x</i> points
     * @param       yPoints an array of <i>y</i> points
     * @param       nPoints the total number of points
     * @see         java.awt.Graphics#drawPolygon(int[], int[], int)
     * @since       JDK1.1
     */
    public void drawPolyline(int xPoints[], int yPoints[],
                             int nPoints) {
        float fromX;
        float fromY;
        float toX;
        float toY;

        if (nPoints > 0) {
            fromX = xPoints[0];
            fromY = yPoints[0];
            for(int i = 1; i < nPoints; i++) {
                toX = xPoints[i];
                toY = yPoints[i];
                draw(new Line2D.Float(fromX, fromY, toX, toY));
                fromX = toX;
                fromY = toY;
            }
        }

    }


    /**
     * Draws a closed polygon defined by
     * arrays of <i>x</i> and <i>y</i> coordinates.
     * Each pair of (<i>x</i>,&nbsp;<i>y</i>) coordinates defines a point.
     * <p>
     * This method draws the polygon defined by <code>nPoint</code> line
     * segments, where the first <code>nPoint&nbsp;-&nbsp;1</code>
     * line segments are line segments from
     * <code>(xPoints[i&nbsp;-&nbsp;1],&nbsp;yPoints[i&nbsp;-&nbsp;1])</code>
     * to <code>(xPoints[i],&nbsp;yPoints[i])</code>, for
     * 1&nbsp;&le;&nbsp;<i>i</i>&nbsp;&le;&nbsp;<code>nPoints</code>.
     * The figure is automatically closed by drawing a line connecting
     * the final point to the first point, if those points are different.
     * @param        xPoints   a an array of <code>x</code> coordinates.
     * @param        yPoints   a an array of <code>y</code> coordinates.
     * @param        nPoints   a the total number of points.
     * @see          java.awt.Graphics#fillPolygon
     * @see          java.awt.Graphics#drawPolyline
     */
    public void drawPolygon(int xPoints[], int yPoints[],
                                     int nPoints) {

        draw(new Polygon(xPoints, yPoints, nPoints));
    }

    /**
     * Draws the outline of a polygon defined by the specified
     * <code>Polygon</code> object.
     * @param        p the polygon to draw.
     * @see          java.awt.Graphics#fillPolygon
     * @see          java.awt.Graphics#drawPolyline
     */
    public void drawPolygon(Polygon p) {
        draw(p);
    }

     /**
     * Fills a closed polygon defined by
     * arrays of <i>x</i> and <i>y</i> coordinates.
     * <p>
     * This method draws the polygon defined by <code>nPoint</code> line
     * segments, where the first <code>nPoint&nbsp;-&nbsp;1</code>
     * line segments are line segments from
     * <code>(xPoints[i&nbsp;-&nbsp;1],&nbsp;yPoints[i&nbsp;-&nbsp;1])</code>
     * to <code>(xPoints[i],&nbsp;yPoints[i])</code>, for
     * 1&nbsp;&le;&nbsp;<i>i</i>&nbsp;&le;&nbsp;<code>nPoints</code>.
     * The figure is automatically closed by drawing a line connecting
     * the final point to the first point, if those points are different.
     * <p>
     * The area inside the polygon is defined using an
     * even-odd fill rule, also known as the alternating rule.
     * @param        xPoints   a an array of <code>x</code> coordinates.
     * @param        yPoints   a an array of <code>y</code> coordinates.
     * @param        nPoints   a the total number of points.
     * @see          java.awt.Graphics#drawPolygon(int[], int[], int)
     */
    public void fillPolygon(int xPoints[], int yPoints[],
                            int nPoints) {

        fill(new Polygon(xPoints, yPoints, nPoints));
    }


    /**
     * Fills the polygon defined by the specified Polygon object with
     * the graphics context's current color.
     * <p>
     * The area inside the polygon is defined using an
     * even-odd fill rule, also known as the alternating rule.
     * @param        p the polygon to fill.
     * @see          java.awt.Graphics#drawPolygon(int[], int[], int)
     */
    public void fillPolygon(Polygon p) {

        fill(p);
    }

    /**
     * Draws the text given by the specified string, using this
     * graphics context's current font and color. The baseline of the
     * first character is at position (<i>x</i>,&nbsp;<i>y</i>) in this
     * graphics context's coordinate system.
     * @param       str      the string to be drawn.
     * @param       x        the <i>x</i> coordinate.
     * @param       y        the <i>y</i> coordinate.
     * @see         java.awt.Graphics#drawBytes
     * @see         java.awt.Graphics#drawChars
     * @since       JDK1.0
     */
    public void drawString(String str, int x, int y) {
        drawString(str, (float) x, (float) y);
    }

    public void drawString(String str, float x, float y) {
        if (str.length() == 0) {
            return;
        }
        TextLayout layout =
            new TextLayout(str, getFont(), getFontRenderContext());
        layout.draw(this, x, y);
    }

    protected void drawString(String str, float x, float y,
                              Font font, FontRenderContext frc, float w) {
        TextLayout layout =
            new TextLayout(str, font, frc);
        Shape textShape =
            layout.getOutline(AffineTransform.getTranslateInstance(x, y));
        fill(textShape);
    }

    /**
     * Draws the text given by the specified iterator, using this
     * graphics context's current color. The iterator has to specify a font
     * for each character. The baseline of the
     * first character is at position (<i>x</i>,&nbsp;<i>y</i>) in this
     * graphics context's coordinate system.
     * @param       iterator the iterator whose text is to be drawn
     * @param       x        the <i>x</i> coordinate.
     * @param       y        the <i>y</i> coordinate.
     * @see         java.awt.Graphics#drawBytes
     * @see         java.awt.Graphics#drawChars
     */
    public void drawString(AttributedCharacterIterator iterator,
                           int x, int y) {
        drawString(iterator, (float) x, (float) y);
    }
    public void drawString(AttributedCharacterIterator iterator,
                           float x, float y) {
        if (iterator == null) {
            throw
                new NullPointerException("attributedcharacteriterator is null");
        }
        TextLayout layout =
            new TextLayout(iterator, getFontRenderContext());
        layout.draw(this, x, y);
    }

    /**
     * Draws a GlyphVector.
     * The rendering attributes applied include the clip, transform,
     * paint or color, and composite attributes.  The GlyphVector specifies
     * individual glyphs from a Font.
     * @param g The GlyphVector to be drawn.
     * @param x,y The coordinates where the glyphs should be drawn.
     * @see #setPaint
     * @see java.awt.Graphics#setColor
     * @see #transform
     * @see #setTransform
     * @see #setComposite
     * @see #clip
     * @see #setClip
     */
    public void drawGlyphVector(GlyphVector g,
                                float x,
                                float y) {

        /* We should not reach here if printingGlyphVector is already true.
         * Add an assert so this can be tested if need be.
         * But also ensure that we do at least render properly by filling
         * the outline.
         */
        if (printingGlyphVector) {
            assert !printingGlyphVector; // ie false.
            fill(g.getOutline(x, y));
            return;
        }

        try {
            printingGlyphVector = true;
            if (RasterPrinterJob.shapeTextProp ||
                !printedSimpleGlyphVector(g, x, y)) {
                fill(g.getOutline(x, y));
            }
        } finally {
            printingGlyphVector = false;
        }
    }

    protected static SoftReference<Hashtable<Font2DHandle,Object>>
        fontMapRef = new SoftReference<Hashtable<Font2DHandle,Object>>(null);

    protected int platformFontCount(Font font, String str) {
        return 0;
    }

    /**
     * Default implementation returns false.
     * Callers of this method must always be prepared for this,
     * and delegate to outlines or some other solution.
     */
    protected boolean printGlyphVector(GlyphVector gv, float x, float y) {
        return false;
    }

    /* GlyphVectors are usually encountered because TextLayout is in use.
     * Some times TextLayout is needed to handle complex text or some
     * rendering attributes trigger it.
     * We try to print GlyphVectors by reconstituting into a String,
     * as that is most recoverable for applications that export to formats
     * such as Postscript or PDF. In some cases (eg where its not complex
     * text and its just that positions aren't what we'd expect) we print
     * one character at a time. positioning individually.
     * Failing that, if we can directly send glyph codes to the printer
     * then we do that (printGlyphVector).
     * As a last resort we return false and let the caller print as filled
     * shapes.
     */
    boolean printedSimpleGlyphVector(GlyphVector g, float x, float y) {

        int flags = g.getLayoutFlags();

        /* We can't handle RTL, re-ordering, complex glyphs etc by
         * reconstituting glyphs into a String. So if any flags besides
         * position adjustments are set, see if we can directly
         * print the GlyphVector as glyph codes, using the positions
         * layout has assigned. If that fails return false;
         */
        if (flags != 0 && flags != GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS) {
            return printGlyphVector(g, x, y);
        }

        Font font = g.getFont();
        Font2D font2D = FontManager.getFont2D(font);
        if (font2D.handle.font2D != font2D) {
            /* suspicious, may be a bad font. lets bail */
            return false;
        }
        Hashtable<Font2DHandle,Object> fontMap;
        synchronized (PathGraphics.class) {
            fontMap = fontMapRef.get();
            if (fontMap == null) {
                fontMap = new Hashtable<Font2DHandle,Object>();
                fontMapRef =
                    new SoftReference<Hashtable<Font2DHandle,Object>>(fontMap);
            }
        }

        int numGlyphs = g.getNumGlyphs();
        int[] glyphCodes = g.getGlyphCodes(0, numGlyphs, null);

        char[] glyphToCharMap = null;
        char[][] mapArray = null;
        CompositeFont cf = null;

        /* Build the needed maps for this font in a synchronized block */
        synchronized (fontMap) {
            if (font2D instanceof CompositeFont) {
                cf = (CompositeFont)font2D;
                int numSlots = cf.getNumSlots();
                mapArray = (char[][])fontMap.get(font2D.handle);
                if (mapArray == null) {
                    mapArray = new char[numSlots][];
                    fontMap.put(font2D.handle, mapArray);
                }
                for (int i=0; i<numGlyphs;i++) {
                    int slot = glyphCodes[i] >>> 24;
                    if (slot >= numSlots) { /* shouldn't happen */
                        return false;
                    }
                    if (mapArray[slot] == null) {
                        Font2D slotFont = cf.getSlotFont(slot);
                        char[] map = (char[])fontMap.get(slotFont.handle);
                        if (map == null) {
                            map = getGlyphToCharMapForFont(slotFont);
                        }
                        mapArray[slot] = map;
                    }
                }
            } else {
                glyphToCharMap = (char[])fontMap.get(font2D.handle);
                if (glyphToCharMap == null) {
                    glyphToCharMap = getGlyphToCharMapForFont(font2D);
                    fontMap.put(font2D.handle, glyphToCharMap);
                }
            }
        }

        char[] chars = new char[numGlyphs];
        if (cf != null) {
            for (int i=0; i<numGlyphs; i++) {
                int gc = glyphCodes[i];
                char[] map = mapArray[gc >>> 24];
                gc = gc & 0xffffff;
                if (map == null) {
                    return false;
                }
                /* X11 symbol & dingbats fonts used only for global metrics,
                 * so the glyph codes we have really refer to Lucida Sans
                 * Regular.
                 * So its possible the glyph code may appear out of range.
                 * Note that later on we double-check the glyph codes that
                 * we get from re-creating the GV from the string are the
                 * same as those we started with.
                 *
                 * If the glyphcode is INVISIBLE_GLYPH_ID then this may
                 * be \t, \n or \r which are mapped to that by layout.
                 * This is a case we can handle. It doesn't matter what
                 * character we use (we use \n) so long as layout maps it
                 * back to this in the verification, since the invisible
                 * glyph isn't visible :)
                 */
                char ch;
                if (gc == CharToGlyphMapper.INVISIBLE_GLYPH_ID) {
                    ch = '\n';
                } else if (gc < 0 || gc >= map.length) {
                    return false;
                } else {
                    ch = map[gc];
                }
                if (ch != CharToGlyphMapper.INVISIBLE_GLYPH_ID) {
                    chars[i] = ch;
                } else {
                    return false;
                }
            }
        } else {
            for (int i=0; i<numGlyphs; i++) {
                int gc = glyphCodes[i];
                char ch;
                if (gc == CharToGlyphMapper.INVISIBLE_GLYPH_ID) {
                    ch = '\n';
                } else if (gc < 0 || gc >= glyphToCharMap.length) {
                    return false;
                } else {
                    ch = glyphToCharMap[gc];
                }
                if (ch != CharToGlyphMapper.INVISIBLE_GLYPH_ID) {
                    chars[i] = ch;
                } else {
                    return false;
                }
            }
        }

        FontRenderContext gvFrc = g.getFontRenderContext();
        GlyphVector gv2 = font.createGlyphVector(gvFrc, chars);
        if (gv2.getNumGlyphs() != numGlyphs) {
            return printGlyphVector(g, x, y);
        }
        int[] glyphCodes2 = gv2.getGlyphCodes(0, numGlyphs, null);
        /*
         * Needed to double-check remapping of X11 symbol & dingbats.
         */
        for (int i=0; i<numGlyphs; i++) {
            if (glyphCodes[i] != glyphCodes2[i]) {
                return printGlyphVector(g, x, y);
            }
        }

        FontRenderContext g2dFrc = getFontRenderContext();
        boolean compatibleFRC = gvFrc.equals(g2dFrc);
        /* If differ only in specifying A-A or a translation, these are
         * also compatible FRC's, and we can do one drawString call.
         */
        if (!compatibleFRC &&
            gvFrc.usesFractionalMetrics() == g2dFrc.usesFractionalMetrics()) {
            AffineTransform gvAT = gvFrc.getTransform();
            AffineTransform g2dAT = getTransform();
            double[] gvMatrix = new double[4];
            double[] g2dMatrix = new double[4];
            gvAT.getMatrix(gvMatrix);
            g2dAT.getMatrix(g2dMatrix);
            compatibleFRC = true;
            for (int i=0;i<4;i++) {
                if (gvMatrix[i] != g2dMatrix[i]) {
                    compatibleFRC = false;
                    break;
                }
            }
        }

        String str = new String(chars, 0, numGlyphs);
        int numFonts = platformFontCount(font, str);
        if (numFonts == 0) {
            return false;
        }

        float[] positions = g.getGlyphPositions(0, numGlyphs, null);
        boolean noPositionAdjustments =
            ((flags & GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS) == 0) ||
            samePositions(gv2, glyphCodes2, glyphCodes, positions);

        /* We have to consider that the application may be directly
         * creating a GlyphVector, rather than one being created by
         * TextLayout or indirectly from drawString. In such a case, if the
         * font has layout attributes, the text may measure differently
         * when we reconstitute it into a String and ask for the length that
         * drawString would use. For example, KERNING will be applied in such
         * a case but that Font attribute is not applied when the application
         * directly created a GlyphVector. So in this case we need to verify
         * that the text measures the same in both cases - ie that the
         * layout attribute has no effect. If it does we can't always
         * use the drawString call unless we can coerce the drawString call
         * into measuring and displaying the string to the same length.
         * That is the case where there is only one font used and we can
         * specify the overall advance of the string. (See below).
         */

        Point2D gvAdvancePt = g.getGlyphPosition(numGlyphs);
        float gvAdvanceX = (float)gvAdvancePt.getX();
        boolean layoutAffectsAdvance = false;
        if (font.hasLayoutAttributes() && printingGlyphVector &&
            noPositionAdjustments) {

            /* If TRACKING is in use then the glyph vector will report
             * position adjustments, then that ought to be sufficient to
             * tell us we can't just ask native to do "drawString". But layout
             * always sets the position adjustment flag, so we don't believe
             * it and verify the positions are really different than
             * createGlyphVector() (with no layout) would create. However
             * inconsistently, TRACKING is applied when creating a GlyphVector,
             * since it doesn't actually require "layout" (even though its
             * considered a layout attribute), it just requires a fractional
             * tweak to the[default]advances. So we need to specifically
             * check for tracking until such time as as we can trust
             * the GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS bit.
             */
            Map<TextAttribute, ?> map = font.getAttributes();
            Object o = map.get(TextAttribute.TRACKING);
            boolean tracking = o != null && (o instanceof Number) &&
                (((Number)o).floatValue() != 0f);

            if (tracking) {
                noPositionAdjustments = false;
            } else {
                Rectangle2D bounds = font.getStringBounds(str, gvFrc);
                float strAdvanceX = (float)bounds.getWidth();
                if (Math.abs(strAdvanceX - gvAdvanceX) > 0.00001) {
                    layoutAffectsAdvance = true;
                }
            }
        }

        if (compatibleFRC && noPositionAdjustments && !layoutAffectsAdvance) {
            drawString(str, x, y, font, gvFrc, 0f);
            return true;
        }

        /* If positions have not been explicitly assigned, we can
         * ask the string to be drawn adjusted to this width.
         * This call is supported only in the PS generator.
         * GDI has API to specify the advance for each glyph in a
         * string which could be used here too, but that is not yet
         * implemented, and we'd need to update the signature of the
         * drawString method to take the advances (ie relative positions)
         * and use that instead of the width.
         */
        if (numFonts == 1 && canDrawStringToWidth() && noPositionAdjustments) {
            drawString(str, x, y, font, gvFrc, gvAdvanceX);
            return true;
        }

        /* In some scripts chars drawn individually do not have the
         * same representation (glyphs) as when combined with other chars.
         * The logic here is erring on the side of caution, in particular
         * in including supplementary characters.
         */
        if (FontManager.isComplexText(chars, 0, chars.length)) {
            return printGlyphVector(g, x, y);
        }

        /* If we reach here we have mapped all the glyphs back
         * one-to-one to simple unicode chars that we know are in the font.
         * We can call "drawChars" on each one of them in turn, setting
         * the position based on the glyph positions.
         * There's typically overhead in this. If numGlyphs is 'large',
         * it may even be better to try printGlyphVector() in this case.
         * This may be less recoverable for apps, but sophisticated apps
         * should be able to recover the text from simple glyph vectors
         * and we can avoid penalising the more common case - although
         * this is already a minority case.
         */
        if (numGlyphs > 10 && printGlyphVector(g, x, y)) {
            return true;
        }

        for (int i=0; i<numGlyphs; i++) {
            String s = new String(chars, i, 1);
            drawString(s, x+positions[i*2], y+positions[i*2+1],
                       font, gvFrc, 0f);
        }
        return true;
    }

    /* The same codes must be in the same positions for this to return true.
     * This would look cleaner if it took the original GV as a parameter but
     * we already have the codes and will need to get the positions array
     * too in most cases anyway. So its cheaper to pass them in.
     * This call wouldn't be necessary if layout didn't always set the
     * FLAG_HAS_POSITION_ADJUSTMENTS even if the default advances are used
     * and there was no re-ordering (this should be fixed some day).
     */
    private boolean samePositions(GlyphVector gv, int[] gvcodes,
                                  int[] origCodes, float[] origPositions) {

        int numGlyphs = gv.getNumGlyphs();
        float[] gvpos = gv.getGlyphPositions(0, numGlyphs, null);

        /* this shouldn't happen here, but just in case */
        if (numGlyphs != gvcodes.length ||  /* real paranoia here */
            origCodes.length != gvcodes.length ||
            origPositions.length != gvpos.length) {
            return false;
        }

        for (int i=0; i<numGlyphs; i++) {
            if (gvcodes[i] != origCodes[i] || gvpos[i] != origPositions[i]) {
                return false;
            }
        }
        return true;
    }

    protected boolean canDrawStringToWidth() {
        return false;
    }

    /* return an array which can map glyphs back to char codes.
     * Glyphs which aren't mapped from a simple unicode code point
     * will have no mapping in this array, and will be assumed to be
     * because of some substitution that we can't handle.
     */
    private static char[] getGlyphToCharMapForFont(Font2D font2D) {
        /* NB Composites report the number of glyphs in slot 0.
         * So if a string uses a char from a later slot, or a fallback slot,
         * it will not be able to use this faster path.
         */
        int numGlyphs = font2D.getNumGlyphs();
        int missingGlyph = font2D.getMissingGlyphCode();
        char[] glyphToCharMap = new char[numGlyphs];
        int glyph;

        for (int i=0;i<numGlyphs; i++) {
            glyphToCharMap[i] = CharToGlyphMapper.INVISIBLE_GLYPH_ID;
        }

        /* Consider refining the ranges to try to map by asking the font
         * what ranges it supports.
         * Since a glyph may be mapped by multiple code points, and this
         * code can't handle that, we always prefer the earlier code point.
         */
        for (char c=0; c<0xFFFF; c++) {
           if (c >= CharToGlyphMapper.HI_SURROGATE_START &&
               c <= CharToGlyphMapper.LO_SURROGATE_END) {
                continue;
            }
            glyph = font2D.charToGlyph(c);
            if (glyph != missingGlyph && glyph < numGlyphs &&
                (glyphToCharMap[glyph] ==
                 CharToGlyphMapper.INVISIBLE_GLYPH_ID)) {
                glyphToCharMap[glyph] = c;
            }
        }
        return glyphToCharMap;
    }

    /**
     * Strokes the outline of a Shape using the settings of the current
     * graphics state.  The rendering attributes applied include the
     * clip, transform, paint or color, composite and stroke attributes.
     * @param s The shape to be drawn.
     * @see #setStroke
     * @see #setPaint
     * @see java.awt.Graphics#setColor
     * @see #transform
     * @see #setTransform
     * @see #clip
     * @see #setClip
     * @see #setComposite
     */
    public void draw(Shape s) {

        fill(getStroke().createStrokedShape(s));
    }

    /**
     * Fills the interior of a Shape using the settings of the current
     * graphics state. The rendering attributes applied include the
     * clip, transform, paint or color, and composite.
     * @see #setPaint
     * @see java.awt.Graphics#setColor
     * @see #transform
     * @see #setTransform
     * @see #setComposite
     * @see #clip
     * @see #setClip
     */
    public void fill(Shape s) {
        Paint paint = getPaint();

        try {
            fill(s, (Color) paint);

        /* The PathGraphics class only supports filling with
         * solid colors and so we do not expect the cast of Paint
         * to Color to fail. If it does fail then something went
         * wrong, like the app draw a page with a solid color but
         * then redrew it with a Gradient.
         */
        } catch (ClassCastException e) {
            throw new IllegalArgumentException("Expected a Color instance");
        }
    }

    public void fill(Shape s, Color color) {
        AffineTransform deviceTransform = getTransform();

        if (getClip() != null) {
            deviceClip(getClip().getPathIterator(deviceTransform));
        }
        deviceFill(s.getPathIterator(deviceTransform), color);
    }

    /**
     * Fill the path defined by <code>pathIter</code>
     * with the specified color.
     * The path is provided in device coordinates.
     */
    protected abstract void deviceFill(PathIterator pathIter, Color color);

    /*
     * Set the clipping path to that defined by
     * the passed in <code>PathIterator</code>.
     */
    protected abstract void deviceClip(PathIterator pathIter);

    /*
     * Draw the outline of the rectangle without using path
     * if supported by platform.
     */
    protected abstract void deviceFrameRect(int x, int y,
                                            int width, int height,
                                            Color color);

    /*
     * Draw a line without using path if supported by platform.
     */
    protected abstract void deviceDrawLine(int xBegin, int yBegin,
                                           int xEnd, int yEnd, Color color);

    /*
     * Fill a rectangle using specified color.
     */
    protected abstract void deviceFillRect(int x, int y,
                                           int width, int height, Color color);

    /* Obtain a BI from known implementations of java.awt.Image
     */
    protected BufferedImage getBufferedImage(Image img) {
        if (img instanceof BufferedImage) {
            // Otherwise we expect a BufferedImage to behave as a standard BI
            return (BufferedImage)img;
        } else if (img instanceof ToolkitImage) {
            // This can be null if the image isn't loaded yet.
            // This is fine as in that case our caller will return
            // as it will only draw a fully loaded image
            return ((ToolkitImage)img).getBufferedImage();
        } else if (img instanceof VolatileImage) {
            // VI needs to make a new BI: this is unavoidable but
            // I don't expect VI's to be "huge" in any case.
            return ((VolatileImage)img).getSnapshot();
        } else {
            // may be null or may be some non-standard Image which
            // shouldn't happen as Image is implemented by the platform
            // not by applications
            // If you add a new Image implementation to the platform you
            // will need to support it here similarly to VI.
            return null;
        }
    }

    /**
     * Return true if the BufferedImage argument has non-opaque
     * bits in it and therefore can not be directly rendered by
     * GDI. Return false if the image is opaque. If this function
     * can not tell for sure whether the image has transparent
     * pixels then it assumes that it does.
     */
    protected boolean hasTransparentPixels(BufferedImage bufferedImage) {
        ColorModel colorModel = bufferedImage.getColorModel();
        boolean hasTransparency = colorModel == null
            ? true
            : colorModel.getTransparency() != ColorModel.OPAQUE;

        /*
         * For the default INT ARGB check the image to see if any pixels are
         * really transparent. If there are no transparent pixels then the
         * transparency of the color model can be ignored.
         * We assume that IndexColorModel images have already been
         * checked for transparency and will be OPAQUE unless they actually
         * have transparent pixels present.
         */
        if (hasTransparency && bufferedImage != null) {
            if (bufferedImage.getType()==BufferedImage.TYPE_INT_ARGB ||
                bufferedImage.getType()==BufferedImage.TYPE_INT_ARGB_PRE) {
                DataBuffer db =  bufferedImage.getRaster().getDataBuffer();
                SampleModel sm = bufferedImage.getRaster().getSampleModel();
                if (db instanceof DataBufferInt &&
                    sm instanceof SinglePixelPackedSampleModel) {
                    SinglePixelPackedSampleModel psm =
                        (SinglePixelPackedSampleModel)sm;
                    // Stealing the data array for reading only...
                    int[] int_data =
                        SunWritableRaster.stealData((DataBufferInt) db, 0);
                    int x = bufferedImage.getMinX();
                    int y = bufferedImage.getMinY();
                    int w = bufferedImage.getWidth();
                    int h = bufferedImage.getHeight();
                    int stride = psm.getScanlineStride();
                    boolean hastranspixel = false;
                    for (int j = y; j < y+h; j++) {
                        int yoff = j * stride;
                        for (int i = x; i < x+w; i++) {
                            if ((int_data[yoff+i] & 0xff000000)!=0xff000000 ) {
                                hastranspixel = true;
                                break;
                            }
                        }
                        if (hastranspixel) {
                            break;
                        }
                    }
                    if (hastranspixel == false) {
                        hasTransparency = false;
                    }
                }
            }
        }

        return hasTransparency;
    }

    protected boolean isBitmaskTransparency(BufferedImage bufferedImage) {
        ColorModel colorModel = bufferedImage.getColorModel();
        return (colorModel != null &&
                colorModel.getTransparency() == ColorModel.BITMASK);
    }


    /* An optimisation for the special case of ICM images which have
     * bitmask transparency.
     */
    protected boolean drawBitmaskImage(BufferedImage bufferedImage,
                                       AffineTransform xform,
                                       Color bgcolor,
                                       int srcX, int srcY,
                                       int srcWidth, int srcHeight) {

        ColorModel colorModel = bufferedImage.getColorModel();
        IndexColorModel icm;
        int [] pixels;

        if (!(colorModel instanceof IndexColorModel)) {
            return false;
        } else {
            icm = (IndexColorModel)colorModel;
        }

        if (colorModel.getTransparency() != ColorModel.BITMASK) {
            return false;
        }

        // to be compatible with 1.1 printing which treated b/g colors
        // with alpha 128 as opaque
        if (bgcolor != null && bgcolor.getAlpha() < 128) {
            return false;
        }

        if ((xform.getType()
             & ~( AffineTransform.TYPE_UNIFORM_SCALE
                  | AffineTransform.TYPE_TRANSLATION
                  | AffineTransform.TYPE_QUADRANT_ROTATION
                  )) != 0) {
            return false;
        }

        if ((getTransform().getType()
             & ~( AffineTransform.TYPE_UNIFORM_SCALE
                  | AffineTransform.TYPE_TRANSLATION
                  | AffineTransform.TYPE_QUADRANT_ROTATION
                  )) != 0) {
            return false;
        }

        BufferedImage subImage = null;
        Raster raster = bufferedImage.getRaster();
        int transpixel = icm.getTransparentPixel();
        byte[] alphas = new byte[icm.getMapSize()];
        icm.getAlphas(alphas);
        if (transpixel >= 0) {
            alphas[transpixel] = 0;
        }

        /* don't just use srcWidth & srcHeight from application - they
         * may exceed the extent of the image - may need to clip.
         * The image xform will ensure that points are still mapped properly.
         */
        int rw = raster.getWidth();
        int rh = raster.getHeight();
        if (srcX > rw || srcY > rh) {
            return false;
        }
        int right, bottom, wid, hgt;
        if (srcX+srcWidth > rw) {
            right = rw;
            wid = right - srcX;
        } else {
            right = srcX+srcWidth;
            wid = srcWidth;
        }
        if (srcY+srcHeight > rh) {
            bottom = rh;
            hgt = bottom - srcY;
        } else {
            bottom = srcY+srcHeight;
            hgt = srcHeight;
        }
        pixels = new int[wid];
        for (int j=srcY; j<bottom; j++) {
            int startx = -1;
            raster.getPixels(srcX, j, wid, 1, pixels);
            for (int i=srcX; i<right; i++) {
                if (alphas[pixels[i-srcX]] == 0) {
                    if (startx >=0) {
                        subImage = bufferedImage.getSubimage(startx, j,
                                                             i-startx, 1);
                        xform.translate(startx, j);
                        drawImageToPlatform(subImage, xform, bgcolor,
                                      0, 0, i-startx, 1, true);
                        xform.translate(-startx, -j);
                        startx = -1;
                    }
                } else if (startx < 0) {
                    startx = i;
                }
            }
            if (startx >= 0) {
                subImage = bufferedImage.getSubimage(startx, j,
                                                     right - startx, 1);
                xform.translate(startx, j);
                drawImageToPlatform(subImage, xform, bgcolor,
                              0, 0, right - startx, 1, true);
                xform.translate(-startx, -j);
            }
        }
        return true;
    }



    /**
     * The various <code>drawImage()</code> methods for
     * <code>PathGraphics</code> are all decomposed
     * into an invocation of <code>drawImageToPlatform</code>.
     * The portion of the passed in image defined by
     * <code>srcX, srcY, srcWidth, and srcHeight</code>
     * is transformed by the supplied AffineTransform and
     * drawn using PS to the printer context.
     *
     * @param   img     The image to be drawn.
     *                  This method does nothing if <code>img</code> is null.
     * @param   xform   Used to tranform the image before drawing.
     *                  This can be null.
     * @param   bgcolor This color is drawn where the image has transparent
     *                  pixels. If this parameter is null then the
     *                  pixels already in the destination should show
     *                  through.
     * @param   srcX    With srcY this defines the upper-left corner
     *                  of the portion of the image to be drawn.
     *
     * @param   srcY    With srcX this defines the upper-left corner
     *                  of the portion of the image to be drawn.
     * @param   srcWidth    The width of the portion of the image to
     *                      be drawn.
     * @param   srcHeight   The height of the portion of the image to
     *                      be drawn.
     * @param   handlingTransparency if being recursively called to
     *                    print opaque region of transparent image
     */
    protected abstract boolean
        drawImageToPlatform(Image img, AffineTransform xform,
                            Color bgcolor,
                            int srcX, int srcY,
                            int srcWidth, int srcHeight,
                            boolean handlingTransparency);

    /**
     * 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.
     * @see      java.awt.Image
     * @see      java.awt.image.ImageObserver
     * @see      java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
     * @since    JDK1.0
     */
    public boolean drawImage(Image img, int x, int y,
                             ImageObserver observer) {

        return drawImage(img, x, y, null, observer);
    }

    /**
     * Draws as much of the specified image as has already been scaled
     * to fit inside the specified rectangle.
     * <p>
     * The image is drawn inside the specified rectangle of this
     * graphics context's coordinate space, and is scaled if
     * necessary. Transparent pixels do not affect whatever pixels
     * are already there.
     * <p>
     * This method returns immediately in all cases, even if the
     * entire image has not yet been scaled, dithered, and converted
     * for the current output device.
     * If the current output representation is not yet complete, then
     * <code>drawImage</code> returns <code>false</code>. As more of
     * the image becomes available, the process that draws the image notifies
     * the image observer by calling its <code>imageUpdate</code> method.
     * <p>
     * A scaled version of an image will not necessarily be
     * available immediately just because an unscaled version of the
     * image has been constructed for this output device.  Each size of
     * the image may be cached separately and generated from the original
     * data in a separate image production sequence.
     * @param    img    the specified image to be drawn.
     * @param    x      the <i>x</i> coordinate.
     * @param    y      the <i>y</i> coordinate.
     * @param    width  the width of the rectangle.
     * @param    height the height of the rectangle.
     * @param    observer    object to be notified as more of
     *                          the image is converted.
     * @see      java.awt.Image
     * @see      java.awt.image.ImageObserver
     * @see      java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
     * @since    JDK1.0
     */
    public boolean drawImage(Image img, int x, int y,
                             int width, int height,
                             ImageObserver observer) {

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

    }

    /*
     * 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 are drawn in the specified
     * background color.
     * <p>
     * This operation is equivalent to filling a rectangle of the
     * width and height of the specified image with the given color and then
     * drawing the image on top of it, but possibly more efficient.
     * <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.
     *                  This method does nothing if <code>img</code> is null.
     * @param    x      the <i>x</i> coordinate.
     * @param    y      the <i>y</i> coordinate.
     * @param    bgcolor the background color to paint under the
     *                   non-opaque portions of the image.
     *                   In this WPathGraphics implementation,
     *                   this parameter can be null in which
     *                   case that background is made a transparent
     *                   white.
     * @param    observer    object to be notified as more of
     *                          the image is converted.
     * @see      java.awt.Image
     * @see      java.awt.image.ImageObserver
     * @see      java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
     * @since    JDK1.0
     */
    public boolean drawImage(Image img, int x, int y,
                             Color bgcolor,
                             ImageObserver observer) {

        if (img == null) {
            return true;
        }

        boolean result;
        int srcWidth = img.getWidth(null);
        int srcHeight = img.getHeight(null);

        if (srcWidth < 0 || srcHeight < 0) {
            result = false;
        } else {
            result = drawImage(img, x, y, srcWidth, srcHeight, bgcolor, observer);
        }

        return result;
    }

    /**
     * Draws as much of the specified image as has already been scaled
     * to fit inside the specified rectangle.
     * <p>
     * The image is drawn inside the specified rectangle of this
     * graphics context's coordinate space, and is scaled if
     * necessary. Transparent pixels are drawn in the specified
     * background color.
     * This operation is equivalent to filling a rectangle of the
     * width and height of the specified image with the given color and then
     * drawing the image on top of it, but possibly more efficient.
     * <p>
     * This method returns immediately in all cases, even if the
     * entire image has not yet been scaled, dithered, and converted
     * for the current output device.
     * If the current output representation is not yet complete 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.
     * <p>
     * A scaled version of an image will not necessarily be
     * available immediately just because an unscaled version of the
     * image has been constructed for this output device.  Each size of
     * the image may be cached separately and generated from the original
     * data in a separate image production sequence.
     * @param    img       the specified image to be drawn.
     *                     This method does nothing if <code>img</code> is null.
     * @param    x         the <i>x</i> coordinate.
     * @param    y         the <i>y</i> coordinate.
     * @param    width     the width of the rectangle.
     * @param    height    the height of the rectangle.
     * @param    bgcolor   the background color to paint under the
     *                         non-opaque portions of the image.
     * @param    observer    object to be notified as more of
     *                          the image is converted.
     * @see      java.awt.Image
     * @see      java.awt.image.ImageObserver
     * @see      java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
     * @since    JDK1.0
     */
    public boolean drawImage(Image img, int x, int y,
                             int width, int height,
                             Color bgcolor,
                             ImageObserver observer) {

        if (img == null) {
            return true;
        }

        boolean result;
        int srcWidth = img.getWidth(null);
        int srcHeight = img.getHeight(null);

        if (srcWidth < 0 || srcHeight < 0) {
            result = false;
        } else {
            result = drawImage(img,
                         x, y, x + width, y + height,
                         0, 0, srcWidth, srcHeight,
                         observer);
        }

        return result;
    }

    /**
     * Draws as much of the specified area of the specified image as is
     * currently available, scaling it on the fly to fit inside the
     * specified area of the destination drawable surface. Transparent pixels
     * do not affect whatever pixels are already there.
     * <p>
     * This method returns immediately in all cases, even if the
     * image area to be drawn has not yet been scaled, dithered, and converted
     * for the current output device.
     * If the current output representation is not yet complete 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.
     * <p>
     * This method always uses the unscaled version of the image
     * to render the scaled rectangle and performs the required
     * scaling on the fly. It does not use a cached, scaled version
     * of the image for this operation. Scaling of the image from source
     * to destination is performed such that the first coordinate
     * of the source rectangle is mapped to the first coordinate of
     * the destination rectangle, and the second source coordinate is
     * mapped to the second destination coordinate. The subimage is
     * scaled and flipped as needed to preserve those mappings.
     * @param       img the specified image to be drawn
     * @param       dx1 the <i>x</i> coordinate of the first corner of the
     *                    destination rectangle.
     * @param       dy1 the <i>y</i> coordinate of the first corner of the
     *                    destination rectangle.
     * @param       dx2 the <i>x</i> coordinate of the second corner of the
     *                    destination rectangle.
     * @param       dy2 the <i>y</i> coordinate of the second corner of the
     *                    destination rectangle.
     * @param       sx1 the <i>x</i> coordinate of the first corner of the
     *                    source rectangle.
     * @param       sy1 the <i>y</i> coordinate of the first corner of the
     *                    source rectangle.
     * @param       sx2 the <i>x</i> coordinate of the second corner of the
     *                    source rectangle.
     * @param       sy2 the <i>y</i> coordinate of the second corner of the
     *                    source rectangle.
     * @param       observer object to be notified as more of the image is
     *                    scaled and converted.
     * @see         java.awt.Image
     * @see         java.awt.image.ImageObserver
     * @see         java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
     * @since       JDK1.1
     */
    public boolean drawImage(Image img,
                             int dx1, int dy1, int dx2, int dy2,
                             int sx1, int sy1, int sx2, int sy2,
                             ImageObserver observer) {

        return drawImage(img,
                         dx1, dy1, dx2, dy2,
                         sx1, sy1, sx2, sy2,
                         null, observer);
    }

    /**
     * Draws as much of the specified area of the specified image as is
     * currently available, scaling it on the fly to fit inside the
     * specified area of the destination drawable surface.
     * <p>
     * Transparent pixels are drawn in the specified background color.
     * This operation is equivalent to filling a rectangle of the
     * width and height of the specified image with the given color and then
     * drawing the image on top of it, but possibly more efficient.
     * <p>
     * This method returns immediately in all cases, even if the
     * image area to be drawn has not yet been scaled, dithered, and converted
     * for the current output device.
     * If the current output representation is not yet complete 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.
     * <p>
     * This method always uses the unscaled version of the image
     * to render the scaled rectangle and performs the required
     * scaling on the fly. It does not use a cached, scaled version
     * of the image for this operation. Scaling of the image from source
     * to destination is performed such that the first coordinate
     * of the source rectangle is mapped to the first coordinate of
     * the destination rectangle, and the second source coordinate is
     * mapped to the second destination coordinate. The subimage is
     * scaled and flipped as needed to preserve those mappings.
     * @param       img the specified image to be drawn
     *                  This method does nothing if <code>img</code> is null.
     * @param       dx1 the <i>x</i> coordinate of the first corner of the
     *                    destination rectangle.
     * @param       dy1 the <i>y</i> coordinate of the first corner of the
     *                    destination rectangle.
     * @param       dx2 the <i>x</i> coordinate of the second corner of the
     *                    destination rectangle.
     * @param       dy2 the <i>y</i> coordinate of the second corner of the
     *                    destination rectangle.
     * @param       sx1 the <i>x</i> coordinate of the first corner of the
     *                    source rectangle.
     * @param       sy1 the <i>y</i> coordinate of the first corner of the
     *                    source rectangle.
     * @param       sx2 the <i>x</i> coordinate of the second corner of the
     *                    source rectangle.
     * @param       sy2 the <i>y</i> coordinate of the second corner of the
     *                    source rectangle.
     * @param       bgcolor the background color to paint under the
     *                    non-opaque portions of the image.
     * @param       observer object to be notified as more of the image is
     *                    scaled and converted.
     * @see         java.awt.Image
     * @see         java.awt.image.ImageObserver
     * @see         java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
     * @since       JDK1.1
     */
    public boolean drawImage(Image img,
                             int dx1, int dy1, int dx2, int dy2,
                             int sx1, int sy1, int sx2, int sy2,
                             Color bgcolor,
                             ImageObserver observer) {

        if (img == null) {
            return true;
        }
        int imgWidth = img.getWidth(null);
        int imgHeight = img.getHeight(null);

        if (imgWidth < 0 || imgHeight < 0) {
            return true;
        }

        int srcWidth = sx2 - sx1;
        int srcHeight = sy2 - sy1;

        /* Create a transform which describes the changes
         * from the source coordinates to the destination
         * coordinates. The scaling is determined by the
         * ratio of the two rectangles, while the translation
         * comes from the difference of their origins.
         */
        float scalex = (float) (dx2 - dx1) / srcWidth;
        float scaley = (float) (dy2 - dy1) / srcHeight;
        AffineTransform xForm
            = new AffineTransform(scalex,
                                  0,
                                  0,
                                  scaley,
                                  dx1 - (sx1 * scalex),
                                  dy1 - (sy1 * scaley));

        /* drawImageToPlatform needs the top-left of the source area and
         * a positive width and height. The xform describes how to map
         * src->dest, so that information is not lost.
         */
        int tmp=0;
        if (sx2 < sx1) {
            tmp = sx1;
            sx1 = sx2;
            sx2 = tmp;
        }
        if (sy2 < sy1) {
            tmp = sy1;
            sy1 = sy2;
            sy2 = tmp;
        }

        /* if src area is beyond the bounds of the image, we must clip it.
         * The transform is based on the specified area, not the clipped one.
         */
        if (sx1 < 0) {
            sx1 = 0;
        } else if (sx1 > imgWidth) { // empty srcArea, nothing to draw
            sx1 = imgWidth;
        }
        if (sx2 < 0) { // empty srcArea, nothing to draw
            sx2 = 0;
        } else if (sx2 > imgWidth) {
            sx2 = imgWidth;
        }
        if (sy1 < 0) {
            sy1 = 0;
        } else if (sy1 > imgHeight) { // empty srcArea
            sy1 = imgHeight;
        }
        if (sy2 < 0) {  // empty srcArea
            sy2 = 0;
        } else if (sy2 > imgHeight) {
            sy2 = imgHeight;
        }

        srcWidth =  sx2 - sx1;
        srcHeight = sy2 - sy1;

        if (srcWidth <= 0 || srcHeight <= 0) {
            return true;
        }

        return drawImageToPlatform(img, xForm, bgcolor,
                                   sx1, sy1, srcWidth, srcHeight, false);


    }

    /**
     * Draws an image, applying a transform from image space into user space
     * before drawing.
     * The transformation from user space into device space is done with
     * the current transform in the Graphics2D.
     * The given transformation is applied to the image before the
     * transform attribute in the Graphics2D state is applied.
     * The rendering attributes applied include the clip, transform,
     * and composite attributes. Note that the result is
     * undefined, if the given transform is noninvertible.
     * @param img The image to be drawn.
     *            This method does nothing if <code>img</code> is null.
     * @param xform The transformation from image space into user space.
     * @param obs The image observer to be notified as more of the image
     * is converted.
     * @see #transform
     * @see #setTransform
     * @see #setComposite
     * @see #clip
     * @see #setClip
     */
    public boolean drawImage(Image img,
                             AffineTransform xform,
                             ImageObserver obs) {

        if (img == null) {
            return true;
        }

        boolean result;
        int srcWidth = img.getWidth(null);
        int srcHeight = img.getHeight(null);

        if (srcWidth < 0 || srcHeight < 0) {
            result = false;
        } else {
            result = drawImageToPlatform(img, xform, null,
                                         0, 0, srcWidth, srcHeight, false);
        }

        return result;
    }

    /**
     * Draws a BufferedImage that is filtered with a BufferedImageOp.
     * The rendering attributes applied include the clip, transform
     * and composite attributes.  This is equivalent to:
     * <pre>
     * img1 = op.filter(img, null);
     * drawImage(img1, new AffineTransform(1f,0f,0f,1f,x,y), null);
     * </pre>
     * @param op The filter to be applied to the image before drawing.
     * @param img The BufferedImage to be drawn.
     *            This method does nothing if <code>img</code> is null.
     * @param x,y The location in user space where the image should be drawn.
     * @see #transform
     * @see #setTransform
     * @see #setComposite
     * @see #clip
     * @see #setClip
     */
    public void drawImage(BufferedImage img,
                          BufferedImageOp op,
                          int x,
                          int y) {

        if (img == null) {
            return;
        }

        int srcWidth = img.getWidth(null);
        int srcHeight = img.getHeight(null);

        if (op != null) {
            img = op.filter(img, null);
        }
        if (srcWidth <= 0 || srcHeight <= 0) {
            return;
        } else {
            AffineTransform xform = new AffineTransform(1f,0f,0f,1f,x,y);
            drawImageToPlatform(img, xform, null,
                                0, 0, srcWidth, srcHeight, false);
        }

    }

    /**
     * Draws an image, applying a transform from image space into user space
     * before drawing.
     * The transformation from user space into device space is done with
     * the current transform in the Graphics2D.
     * The given transformation is applied to the image before the
     * transform attribute in the Graphics2D state is applied.
     * The rendering attributes applied include the clip, transform,
     * and composite attributes. Note that the result is
     * undefined, if the given transform is noninvertible.
     * @param img The image to be drawn.
     *            This method does nothing if <code>img</code> is null.
     * @param xform The transformation from image space into user space.
     * @see #transform
     * @see #setTransform
     * @see #setComposite
     * @see #clip
     * @see #setClip
     */
    public void drawRenderedImage(RenderedImage img,
                                  AffineTransform xform) {

        if (img == null) {
            return;
        }

        BufferedImage bufferedImage = null;
        int srcWidth = img.getWidth();
        int srcHeight = img.getHeight();

        if (srcWidth <= 0 || srcHeight <= 0) {
            return;
        }

        if (img instanceof BufferedImage) {
            bufferedImage = (BufferedImage) img;
        } else {
            bufferedImage = new BufferedImage(srcWidth, srcHeight,
                                              BufferedImage.TYPE_INT_ARGB);
            Graphics2D imageGraphics = bufferedImage.createGraphics();
            imageGraphics.drawRenderedImage(img, xform);
        }

        drawImageToPlatform(bufferedImage, xform, null,
                            0, 0, srcWidth, srcHeight, false);

    }

}
