/*
 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.java2d;

import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.nio.*;

import sun.awt.image.*;
import sun.java2d.loops.*;
import sun.java2d.pipe.*;
import sun.lwawt.macosx.*;

public class CRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe, DrawImagePipe {
    native static void init();

    // cache of the runtime options
    static {
        init(); // initialize coordinate tables for shapes
    }

    native void doLine(SurfaceData sData, float x1, float y1, float x2, float y2);

    public void drawLine(SunGraphics2D sg2d, int x1, int y1, int x2, int y2) {
        drawLine(sg2d, (float) x1, (float) y1, (float) x2, (float) y2);
    }

    Line2D lineToShape;

    public void drawLine(SunGraphics2D sg2d, float x1, float y1, float x2, float y2) {
        OSXSurfaceData surfaceData = (OSXSurfaceData) sg2d.getSurfaceData();
        if ((sg2d.strokeState != SunGraphics2D.STROKE_CUSTOM) && (OSXSurfaceData.IsSimpleColor(sg2d.paint))) {
            surfaceData.doLine(this, sg2d, x1, y1, x2, y2);
        } else {
            if (lineToShape == null) {
                synchronized (this) {
                    if (lineToShape == null) {
                        lineToShape = new Line2D.Float();
                    }
                }
            }
            synchronized (lineToShape) {
                lineToShape.setLine(x1, y1, x2, y2);
                drawfillShape(sg2d, sg2d.stroke.createStrokedShape(lineToShape), true, true);
            }
        }
    }

    native void doRect(SurfaceData sData, float x, float y, float width, float height, boolean isfill);

    public void drawRect(SunGraphics2D sg2d, int x, int y, int width, int height) {
        drawRect(sg2d, (float) x, (float) y, (float) width, (float) height);
    }

    Rectangle2D rectToShape;

    public void drawRect(SunGraphics2D sg2d, float x, float y, float width, float height) {
        if ((width < 0) || (height < 0)) return;

        OSXSurfaceData surfaceData = (OSXSurfaceData) sg2d.getSurfaceData();
        if ((sg2d.strokeState != SunGraphics2D.STROKE_CUSTOM) && (OSXSurfaceData.IsSimpleColor(sg2d.paint))) {
            surfaceData.doRect(this, sg2d, x, y, width, height, false);
        } else {
            if (rectToShape == null) {
                synchronized (this) {
                    if (rectToShape == null) {
                        rectToShape = new Rectangle2D.Float();
                    }
                }
            }
            synchronized (rectToShape) {
                rectToShape.setRect(x, y, width, height);
                drawfillShape(sg2d, sg2d.stroke.createStrokedShape(rectToShape), true, true);
            }
        }
    }

    public void fillRect(SunGraphics2D sg2d, int x, int y, int width, int height) {
        fillRect(sg2d, (float) x, (float) y, (float) width, (float) height);
    }

    public void fillRect(SunGraphics2D sg2d, float x, float y, float width, float height) {
        if ((width >= 0) && (height >= 0)) {
            OSXSurfaceData surfaceData = (OSXSurfaceData) sg2d.getSurfaceData();
            surfaceData.doRect(this, sg2d, x, y, width, height, true);
        }
    }

    native void doRoundRect(SurfaceData sData, float x, float y, float width, float height, float arcW, float arcH, boolean isfill);

    public void drawRoundRect(SunGraphics2D sg2d, int x, int y, int width, int height, int arcWidth, int arcHeight) {
        drawRoundRect(sg2d, (float) x, (float) y, (float) width, (float) height, (float) arcWidth, (float) arcHeight);
    }

    RoundRectangle2D roundrectToShape;

    public void drawRoundRect(SunGraphics2D sg2d, float x, float y, float width, float height, float arcWidth, float arcHeight) {
        if ((width < 0) || (height < 0)) return;

        OSXSurfaceData surfaceData = (OSXSurfaceData) sg2d.getSurfaceData();
        if ((sg2d.strokeState != SunGraphics2D.STROKE_CUSTOM) && (OSXSurfaceData.IsSimpleColor(sg2d.paint))) {
            surfaceData.doRoundRect(this, sg2d, x, y, width, height, arcWidth, arcHeight, false);
        } else {
            if (roundrectToShape == null) {
                synchronized (this) {
                    if (roundrectToShape == null) {
                        roundrectToShape = new RoundRectangle2D.Float();
                    }
                }
            }
            synchronized (roundrectToShape) {
                roundrectToShape.setRoundRect(x, y, width, height, arcWidth, arcHeight);
                drawfillShape(sg2d, sg2d.stroke.createStrokedShape(roundrectToShape), true, true);
            }
        }
    }

    public void fillRoundRect(SunGraphics2D sg2d, int x, int y, int width, int height, int arcWidth, int arcHeight) {
        fillRoundRect(sg2d, (float) x, (float) y, (float) width, (float) height, (float) arcWidth, (float) arcHeight);
    }

    public void fillRoundRect(SunGraphics2D sg2d, float x, float y, float width, float height, float arcWidth, float arcHeight) {
        if ((width < 0) || (height < 0)) return;
        OSXSurfaceData surfaceData = (OSXSurfaceData) sg2d.getSurfaceData();
        surfaceData.doRoundRect(this, sg2d, x, y, width, height, arcWidth, arcHeight, true);
    }

    native void doOval(SurfaceData sData, float x, float y, float width, float height, boolean isfill);

    public void drawOval(SunGraphics2D sg2d, int x, int y, int width, int height) {
        drawOval(sg2d, (float) x, (float) y, (float) width, (float) height);
    }

    Ellipse2D ovalToShape;

    public void drawOval(SunGraphics2D sg2d, float x, float y, float width, float height) {
        if ((width < 0) || (height < 0)) return;

        OSXSurfaceData surfaceData = (OSXSurfaceData) sg2d.getSurfaceData();
        if ((sg2d.strokeState != SunGraphics2D.STROKE_CUSTOM) && (OSXSurfaceData.IsSimpleColor(sg2d.paint))) {
            surfaceData.doOval(this, sg2d, x, y, width, height, false);
        } else {
            if (ovalToShape == null) {
                synchronized (this) {
                    if (ovalToShape == null) {
                        ovalToShape = new Ellipse2D.Float();
                    }
                }
            }
            synchronized (ovalToShape) {
                ovalToShape.setFrame(x, y, width, height);
                drawfillShape(sg2d, sg2d.stroke.createStrokedShape(ovalToShape), true, true);
            }
        }
    }

    public void fillOval(SunGraphics2D sg2d, int x, int y, int width, int height) {
        fillOval(sg2d, (float) x, (float) y, (float) width, (float) height);
    }

    public void fillOval(SunGraphics2D sg2d, float x, float y, float width, float height) {
        if ((width < 0) || (height < 0)) return;
        OSXSurfaceData surfaceData = (OSXSurfaceData) sg2d.getSurfaceData();
        surfaceData.doOval(this, sg2d, x, y, width, height, true);
    }

    native void doArc(SurfaceData sData, float x, float y, float width, float height, float angleStart, float angleExtent, int type, boolean isfill);

    public void drawArc(SunGraphics2D sg2d, int x, int y, int width, int height, int startAngle, int arcAngle) {
        drawArc(sg2d, x, y, width, height, startAngle, arcAngle, Arc2D.OPEN);
    }

    Arc2D arcToShape;

    public void drawArc(SunGraphics2D sg2d, float x, float y, float width, float height, float startAngle, float arcAngle, int type) {
        if ((width < 0) || (height < 0)) return;

        OSXSurfaceData surfaceData = (OSXSurfaceData) sg2d.getSurfaceData();
        if ((sg2d.strokeState != SunGraphics2D.STROKE_CUSTOM) && (OSXSurfaceData.IsSimpleColor(sg2d.paint))) {
            surfaceData.doArc(this, sg2d, x, y, width, height, startAngle, arcAngle, type, false);
        } else {
            if (arcToShape == null) {
                synchronized (this) {
                    if (arcToShape == null) {
                        arcToShape = new Arc2D.Float();
                    }
                }
            }
            synchronized (arcToShape) {
                arcToShape.setArc(x, y, width, height, startAngle, arcAngle, type);
                drawfillShape(sg2d, sg2d.stroke.createStrokedShape(arcToShape), true, true);
            }
        }
    }

    public void fillArc(SunGraphics2D sg2d, int x, int y, int width, int height, int startAngle, int arcAngle) {
        fillArc(sg2d, x, y, width, height, startAngle, arcAngle, Arc2D.PIE);
    }

    public void fillArc(SunGraphics2D sg2d, float x, float y, float width, float height, float startAngle, float arcAngle, int type) {
        if ((width < 0) || (height < 0)) return;

        OSXSurfaceData surfaceData = (OSXSurfaceData) sg2d.getSurfaceData();
        surfaceData.doArc(this, sg2d, x, y, width, height, startAngle, arcAngle, type, true);
    }

    native void doPoly(SurfaceData sData, int[] xpoints, int[] ypoints, int npoints, boolean ispolygon, boolean isfill);

    public void drawPolyline(SunGraphics2D sg2d, int xpoints[], int ypoints[], int npoints) {
        OSXSurfaceData surfaceData = (OSXSurfaceData) sg2d.getSurfaceData();
        if ((sg2d.strokeState != SunGraphics2D.STROKE_CUSTOM) && (OSXSurfaceData.IsSimpleColor(sg2d.paint))) {
            surfaceData.doPolygon(this, sg2d, xpoints, ypoints, npoints, false, false);
        } else {
            GeneralPath polyToShape = new GeneralPath();
            polyToShape.moveTo(xpoints[0], ypoints[0]);
            for (int i = 1; i < npoints; i++) {
                polyToShape.lineTo(xpoints[i], ypoints[i]);
            }
            drawfillShape(sg2d, sg2d.stroke.createStrokedShape(polyToShape), true, true);
        }
    }

    public void drawPolygon(SunGraphics2D sg2d, int xpoints[], int ypoints[], int npoints) {
        OSXSurfaceData surfaceData = (OSXSurfaceData) sg2d.getSurfaceData();
        if ((sg2d.strokeState != SunGraphics2D.STROKE_CUSTOM) && (OSXSurfaceData.IsSimpleColor(sg2d.paint))) {
            surfaceData.doPolygon(this, sg2d, xpoints, ypoints, npoints, true, false);
        } else {
            GeneralPath polyToShape = new GeneralPath();
            polyToShape.moveTo(xpoints[0], ypoints[0]);
            for (int i = 1; i < npoints; i++) {
                polyToShape.lineTo(xpoints[i], ypoints[i]);
            }
            polyToShape.lineTo(xpoints[0], ypoints[0]);
            drawfillShape(sg2d, sg2d.stroke.createStrokedShape(polyToShape), true, true);
        }
    }

    public void fillPolygon(SunGraphics2D sg2d, int xpoints[], int ypoints[], int npoints) {
        OSXSurfaceData surfaceData = (OSXSurfaceData) sg2d.getSurfaceData();
        surfaceData.doPolygon(this, sg2d, xpoints, ypoints, npoints, true, true);
    }

    native void doShape(SurfaceData sData, int length, FloatBuffer coordinates, IntBuffer types, int windingRule, boolean isfill, boolean shouldApplyOffset);

    void drawfillShape(SunGraphics2D sg2d, Shape s, boolean isfill, boolean shouldApplyOffset) {
        if (s == null) { throw new NullPointerException(); }

        OSXSurfaceData surfaceData = (OSXSurfaceData) sg2d.getSurfaceData();
        // TODO:
        boolean sOptimizeShapes = true;
        if (sOptimizeShapes && OSXSurfaceData.IsSimpleColor(sg2d.paint)) {
            if (s instanceof Rectangle2D) {
                Rectangle2D rectangle = (Rectangle2D) s;

                float x = (float) rectangle.getX();
                float y = (float) rectangle.getY();
                float w = (float) rectangle.getWidth();
                float h = (float) rectangle.getHeight();
                if (isfill) {
                    fillRect(sg2d, x, y, w, h);
                } else {
                    drawRect(sg2d, x, y, w, h);
                }
            } else if (s instanceof Ellipse2D) {
                Ellipse2D ellipse = (Ellipse2D) s;

                float x = (float) ellipse.getX();
                float y = (float) ellipse.getY();
                float w = (float) ellipse.getWidth();
                float h = (float) ellipse.getHeight();

                if (isfill) {
                    fillOval(sg2d, x, y, w, h);
                } else {
                    drawOval(sg2d, x, y, w, h);
                }
            } else if (s instanceof Arc2D) {
                Arc2D arc = (Arc2D) s;

                float x = (float) arc.getX();
                float y = (float) arc.getY();
                float w = (float) arc.getWidth();
                float h = (float) arc.getHeight();
                float as = (float) arc.getAngleStart();
                float ae = (float) arc.getAngleExtent();

                if (isfill) {
                    fillArc(sg2d, x, y, w, h, as, ae, arc.getArcType());
                } else {
                    drawArc(sg2d, x, y, w, h, as, ae, arc.getArcType());
                }
            } else if (s instanceof RoundRectangle2D) {
                RoundRectangle2D roundrect = (RoundRectangle2D) s;

                float x = (float) roundrect.getX();
                float y = (float) roundrect.getY();
                float w = (float) roundrect.getWidth();
                float h = (float) roundrect.getHeight();
                float aw = (float) roundrect.getArcWidth();
                float ah = (float) roundrect.getArcHeight();

                if (isfill) {
                    fillRoundRect(sg2d, x, y, w, h, aw, ah);
                } else {
                    drawRoundRect(sg2d, x, y, w, h, aw, ah);
                }
            } else if (s instanceof Line2D) {
                Line2D line = (Line2D) s;

                float x1 = (float) line.getX1();
                float y1 = (float) line.getY1();
                float x2 = (float) line.getX2();
                float y2 = (float) line.getY2();

                drawLine(sg2d, x1, y1, x2, y2);
            } else if (s instanceof Point2D) {
                Point2D point = (Point2D) s;

                float x = (float) point.getX();
                float y = (float) point.getY();

                drawLine(sg2d, x, y, x, y);
            } else {
                GeneralPath gp;

                if (s instanceof GeneralPath) {
                    gp = (GeneralPath) s;
                } else {
                    gp = new GeneralPath(s);
                }

                PathIterator pi = gp.getPathIterator(null);
                if (pi.isDone() == false) {
                    surfaceData.drawfillShape(this, sg2d, gp, isfill, shouldApplyOffset);
                }
            }
        } else {
            GeneralPath gp;

            if (s instanceof GeneralPath) {
                gp = (GeneralPath) s;
            } else {
                gp = new GeneralPath(s);
            }

            PathIterator pi = gp.getPathIterator(null);
            if (pi.isDone() == false) {
                surfaceData.drawfillShape(this, sg2d, gp, isfill, shouldApplyOffset);
            }
        }
    }

    public void draw(SunGraphics2D sg2d, Shape s) {
        OSXSurfaceData surfaceData = (OSXSurfaceData) sg2d.getSurfaceData();
        if ((sg2d.strokeState != SunGraphics2D.STROKE_CUSTOM) && (OSXSurfaceData.IsSimpleColor(sg2d.paint))) {
            drawfillShape(sg2d, s, false, true);
        } else {
            drawfillShape(sg2d, sg2d.stroke.createStrokedShape(s), true, true);
        }
    }

    public void fill(SunGraphics2D sg2d, Shape s) {
        drawfillShape(sg2d, s, true, false);
    }

    native void doImage(SurfaceData sData, SurfaceData img, boolean fliph, boolean flipv, int w, int h, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh);

    // Copy img to scaled sg2d @ x,y with width height
    public boolean scaleImage(SunGraphics2D sg2d, Image img, int x, int y, int width, int height, Color bgColor) {
        OSXSurfaceData surfaceData = (OSXSurfaceData) sg2d.getSurfaceData();

        int sx = 0;
        int sy = 0;
        int iw = img.getWidth(null);
        int ih = img.getHeight(null);

        return scaleImage(sg2d, img, x, y, x + width, y + height, sx, sy, sx + iw, sy + ih, bgColor);
    }

    // Copy img, clipped to sx1, sy1 by sx2, sy2 to dx1, dy2 by dx2, dy2
    public boolean scaleImage(SunGraphics2D sg2d, Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgColor) {

        // System.err.println("scaleImage");
        // System.err.println("    sx1="+sx1+", sy1="+sy1+", sx2="+sx2+", sy2="+sy2);
        // System.err.println("    dx1="+dx1+", dy1="+dy1+", dx2="+dx2+", dy2="+dy2);

        int srcW, srcH, dstW, dstH;
        int srcX, srcY, dstX, dstY;
        boolean srcWidthFlip = false;
        boolean srcHeightFlip = false;
        boolean dstWidthFlip = false;
        boolean dstHeightFlip = false;

        if (sx2 > sx1) {
            srcW = sx2 - sx1;
            srcX = sx1;
        } else {
            srcWidthFlip = true;
            srcW = sx1 - sx2;
            srcX = sx2;
        }
        if (sy2 > sy1) {
            srcH = sy2 - sy1;
            srcY = sy1;
        } else {
            srcHeightFlip = true;
            srcH = sy1 - sy2;
            srcY = sy2;
        }
        if (dx2 > dx1) {
            dstW = dx2 - dx1;
            dstX = dx1;
        } else {
            dstW = dx1 - dx2;
            dstWidthFlip = true;
            dstX = dx2;
        }
        if (dy2 > dy1) {
            dstH = dy2 - dy1;
            dstY = dy1;
        } else {
            dstH = dy1 - dy2;
            dstHeightFlip = true;
            dstY = dy2;
        }
        if (srcW <= 0 || srcH <= 0) { return true; }

        boolean flipv = (srcHeightFlip != dstHeightFlip);
        boolean fliph = (srcWidthFlip != dstWidthFlip);

        return blitImage(sg2d, img, fliph, flipv, srcX, srcY, srcW, srcH, dstX, dstY, dstW, dstH, bgColor);
    }

    protected boolean blitImage(SunGraphics2D sg2d, Image img, boolean fliph, boolean flipv, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, Color bgColor) {
        CPrinterSurfaceData surfaceData = (CPrinterSurfaceData)sg2d.getSurfaceData();
        OSXOffScreenSurfaceData imgSurfaceData = (OSXOffScreenSurfaceData) OSXOffScreenSurfaceData.createNewSurface((BufferedImage)img);
        surfaceData.blitImage(this, sg2d, imgSurfaceData, fliph, flipv, sx, sy, sw, sh, dx, dy, dw, dh, bgColor);
        return true;
    }

    // Copy img to sg2d @ x, y
    protected boolean copyImage(SunGraphics2D sg2d, Image img, int dx, int dy, Color bgColor) {
        if (img == null) { return true; }

        int sx = 0;
        int sy = 0;
        int width = img.getWidth(null);
        int height = img.getHeight(null);

        return blitImage(sg2d, img, false, false, sx, sy, width, height, dx, dy, width, height, bgColor);
    }

    // Copy img, clipped to sx, sy with width, height to sg2d @ dx, dy
    protected boolean copyImage(SunGraphics2D sg2d, Image img, int dx, int dy, int sx, int sy, int width, int height, Color bgColor) {
        return blitImage(sg2d, img, false, false, sx, sy, width, height, dx, dy, width, height, bgColor);
    }

    protected void transformImage(SunGraphics2D sg2d, Image img, int x, int y, BufferedImageOp op, AffineTransform xf, Color bgColor) {
        if (img != null) {
            int iw = img.getWidth(null);
            int ih = img.getHeight(null);

            if ((op != null) && (img instanceof BufferedImage)) {
                if (((BufferedImage) img).getType() == BufferedImage.TYPE_CUSTOM) {
                    // BufferedImageOp can not handle custom images
                    BufferedImage dest = null;
                    dest = new BufferedImage(iw, ih, BufferedImage.TYPE_INT_ARGB_PRE);
                    Graphics g = dest.createGraphics();
                    g.drawImage(img, 0, 0, null);
                    g.dispose();
                    img = op.filter(dest, null);
                } else {
                    // sun.awt.image.BufImgSurfaceData.createData((BufferedImage)img).finishLazyDrawing();
                    img = op.filter((BufferedImage) img, null);
                }

                iw = img.getWidth(null);
                ih = img.getHeight(null);
            }

            if (xf != null) {
                AffineTransform reset = sg2d.getTransform();
                sg2d.transform(xf);
                scaleImage(sg2d, img, x, y, x + iw, y + ih, 0, 0, iw, ih, bgColor);
                sg2d.setTransform(reset);
            } else {
                scaleImage(sg2d, img, x, y, x + iw, y + ih, 0, 0, iw, ih, bgColor);
            }
        } else {
            throw new NullPointerException();
        }
    }

    // copied from DrawImage.java
    protected boolean imageReady(sun.awt.image.ToolkitImage sunimg, ImageObserver observer) {
        if (sunimg.hasError()) {
            if (observer != null) {
                observer.imageUpdate(sunimg, ImageObserver.ERROR | ImageObserver.ABORT, -1, -1, -1, -1);
            }
            return false;
        }
        return true;
    }

    // copied from DrawImage.java
    public boolean copyImage(SunGraphics2D sg2d, Image img, int x, int y, Color bgColor, ImageObserver observer) {
        if (img == null) { throw new NullPointerException(); }

        if (!(img instanceof sun.awt.image.ToolkitImage)) { return copyImage(sg2d, img, x, y, bgColor); }

        sun.awt.image.ToolkitImage sunimg = (sun.awt.image.ToolkitImage) img;
        if (!imageReady(sunimg, observer)) { return false; }
        ImageRepresentation ir = sunimg.getImageRep();
        return ir.drawToBufImage(sg2d, sunimg, x, y, bgColor, observer);
    }

    // copied from DrawImage.java
    public boolean copyImage(SunGraphics2D sg2d, Image img, int dx, int dy, int sx, int sy, int width, int height, Color bgColor, ImageObserver observer) {
        if (img == null) { throw new NullPointerException(); }

        if (!(img instanceof sun.awt.image.ToolkitImage)) { return copyImage(sg2d, img, dx, dy, sx, sy, width, height, bgColor); }

        sun.awt.image.ToolkitImage sunimg = (sun.awt.image.ToolkitImage) img;
        if (!imageReady(sunimg, observer)) { return false; }
        ImageRepresentation ir = sunimg.getImageRep();
        return ir.drawToBufImage(sg2d, sunimg, dx, dy, (dx + width), (dy + height), sx, sy, (sx + width), (sy + height), null, observer);
    }

    // copied from DrawImage.java
    public boolean scaleImage(SunGraphics2D sg2d, Image img, int x, int y, int width, int height, Color bgColor, ImageObserver observer) {
        if (img == null) { throw new NullPointerException(); }

        if (!(img instanceof sun.awt.image.ToolkitImage)) { return scaleImage(sg2d, img, x, y, width, height, bgColor); }

        sun.awt.image.ToolkitImage sunimg = (sun.awt.image.ToolkitImage) img;
        if (!imageReady(sunimg, observer)) { return false; }
        ImageRepresentation ir = sunimg.getImageRep();
        return ir.drawToBufImage(sg2d, sunimg, x, y, width, height, bgColor, observer);
    }

    // copied from DrawImage.java
    public boolean scaleImage(SunGraphics2D sg2d, 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) { throw new NullPointerException(); }

        if (!(img instanceof sun.awt.image.ToolkitImage)) { return scaleImage(sg2d, img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bgColor); }

        sun.awt.image.ToolkitImage sunimg = (sun.awt.image.ToolkitImage) img;
        if (!imageReady(sunimg, observer)) { return false; }
        ImageRepresentation ir = sunimg.getImageRep();
        return ir.drawToBufImage(sg2d, sunimg, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bgColor, observer);
    }

    // copied from DrawImage.java
    public boolean transformImage(SunGraphics2D sg2d, Image img, AffineTransform atfm, ImageObserver observer) {
        if (img == null) { throw new NullPointerException(); }

        if (!(img instanceof sun.awt.image.ToolkitImage)) {
            transformImage(sg2d, img, 0, 0, null, atfm, null);
            return true;
        }

        sun.awt.image.ToolkitImage sunimg = (sun.awt.image.ToolkitImage) img;
        if (!imageReady(sunimg, observer)) { return false; }
        ImageRepresentation ir = sunimg.getImageRep();
        return ir.drawToBufImage(sg2d, sunimg, atfm, observer);
    }

    // copied from DrawImage.java
    public void transformImage(SunGraphics2D sg2d, BufferedImage img, BufferedImageOp op, int x, int y) {
        if (img != null) {
            transformImage(sg2d, img, x, y, op, null, null);
        } else {
            throw new NullPointerException();
        }
    }

    public CRenderer traceWrap() {
        return new Tracer();
    }

    public static class Tracer extends CRenderer {
        void doLine(SurfaceData sData, float x1, float y1, float x2, float y2) {
            GraphicsPrimitive.tracePrimitive("QuartzLine");
            super.doLine(sData, x1, y1, x2, y2);
        }

        void doRect(SurfaceData sData, float x, float y, float width, float height, boolean isfill) {
            GraphicsPrimitive.tracePrimitive("QuartzRect");
            super.doRect(sData, x, y, width, height, isfill);
        }

        void doRoundRect(SurfaceData sData, float x, float y, float width, float height, float arcW, float arcH, boolean isfill) {
            GraphicsPrimitive.tracePrimitive("QuartzRoundRect");
            super.doRoundRect(sData, x, y, width, height, arcW, arcH, isfill);
        }

        void doOval(SurfaceData sData, float x, float y, float width, float height, boolean isfill) {
            GraphicsPrimitive.tracePrimitive("QuartzOval");
            super.doOval(sData, x, y, width, height, isfill);
        }

        void doArc(SurfaceData sData, float x, float y, float width, float height, float angleStart, float angleExtent, int type, boolean isfill) {
            GraphicsPrimitive.tracePrimitive("QuartzArc");
            super.doArc(sData, x, y, width, height, angleStart, angleExtent, type, isfill);
        }

        void doPoly(SurfaceData sData, int[] xpoints, int[] ypoints, int npoints, boolean ispolygon, boolean isfill) {
            GraphicsPrimitive.tracePrimitive("QuartzDoPoly");
            super.doPoly(sData, xpoints, ypoints, npoints, ispolygon, isfill);
        }

        void doShape(SurfaceData sData, int length, FloatBuffer coordinates, IntBuffer types, int windingRule, boolean isfill, boolean shouldApplyOffset) {
            GraphicsPrimitive.tracePrimitive("QuartzFillOrDrawShape");
            super.doShape(sData, length, coordinates, types, windingRule, isfill, shouldApplyOffset);
        }

        void doImage(SurfaceData sData, SurfaceData img, boolean fliph, boolean flipv, int w, int h, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh) {
            GraphicsPrimitive.tracePrimitive("QuartzDrawImage");
            super.doImage(sData, img, fliph, flipv, w, h, sx, sy, sw, sh, dx, dy, dw, dh);
        }
    }
}
