/*
 * Copyright 1998-2006 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.
 */

/*
 * @author Charlton Innovations, Inc.
 */

package sun.java2d.loops;

import java.awt.image.WritableRaster;
import java.awt.image.DataBuffer;
import java.awt.image.ColorModel;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.geom.AffineTransform;
import sun.java2d.pipe.Region;
import sun.java2d.pipe.SpanIterator;
import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
import sun.java2d.loops.ProcessPath;
import sun.font.GlyphList;

/**
 * GeneralRenderer collection
 * Basically, a collection of components which permit basic
 * rendering to occur on rasters of any format
 */

public final class GeneralRenderer {
    public static void register() {
        Class owner = GeneralRenderer.class;
        GraphicsPrimitive[] primitives = {
            new  GraphicsPrimitiveProxy(owner, "SetFillRectANY",
                                        FillRect.methodSignature,
                                        FillRect.primTypeID,
                                        SurfaceType.AnyColor,
                                        CompositeType.SrcNoEa,
                                        SurfaceType.Any),
            new  GraphicsPrimitiveProxy(owner, "SetFillPathANY",
                                        FillPath.methodSignature,
                                        FillPath.primTypeID,
                                        SurfaceType.AnyColor,
                                        CompositeType.SrcNoEa,
                                        SurfaceType.Any),
            new  GraphicsPrimitiveProxy(owner, "SetFillSpansANY",
                                        FillSpans.methodSignature,
                                        FillSpans.primTypeID,
                                        SurfaceType.AnyColor,
                                        CompositeType.SrcNoEa,
                                        SurfaceType.Any),
            new  GraphicsPrimitiveProxy(owner, "SetDrawLineANY",
                                        DrawLine.methodSignature,
                                        DrawLine.primTypeID,
                                        SurfaceType.AnyColor,
                                        CompositeType.SrcNoEa,
                                        SurfaceType.Any),
            new  GraphicsPrimitiveProxy(owner, "SetDrawPolygonsANY",
                                        DrawPolygons.methodSignature,
                                        DrawPolygons.primTypeID,
                                        SurfaceType.AnyColor,
                                        CompositeType.SrcNoEa,
                                        SurfaceType.Any),
            new  GraphicsPrimitiveProxy(owner, "SetDrawPathANY",
                                        DrawPath.methodSignature,
                                        DrawPath.primTypeID,
                                        SurfaceType.AnyColor,
                                        CompositeType.SrcNoEa,
                                        SurfaceType.Any),
            new  GraphicsPrimitiveProxy(owner, "SetDrawRectANY",
                                        DrawRect.methodSignature,
                                        DrawRect.primTypeID,
                                        SurfaceType.AnyColor,
                                        CompositeType.SrcNoEa,
                                        SurfaceType.Any),

            new  GraphicsPrimitiveProxy(owner, "XorFillRectANY",
                                        FillRect.methodSignature,
                                        FillRect.primTypeID,
                                        SurfaceType.AnyColor,
                                        CompositeType.Xor,
                                        SurfaceType.Any),
            new  GraphicsPrimitiveProxy(owner, "XorFillPathANY",
                                        FillPath.methodSignature,
                                        FillPath.primTypeID,
                                        SurfaceType.AnyColor,
                                        CompositeType.Xor,
                                        SurfaceType.Any),
            new  GraphicsPrimitiveProxy(owner, "XorFillSpansANY",
                                        FillSpans.methodSignature,
                                        FillSpans.primTypeID,
                                        SurfaceType.AnyColor,
                                        CompositeType.Xor,
                                        SurfaceType.Any),
            new  GraphicsPrimitiveProxy(owner, "XorDrawLineANY",
                                        DrawLine.methodSignature,
                                        DrawLine.primTypeID,
                                        SurfaceType.AnyColor,
                                        CompositeType.Xor,
                                        SurfaceType.Any),
            new  GraphicsPrimitiveProxy(owner, "XorDrawPolygonsANY",
                                        DrawPolygons.methodSignature,
                                        DrawPolygons.primTypeID,
                                        SurfaceType.AnyColor,
                                        CompositeType.Xor,
                                        SurfaceType.Any),
            new  GraphicsPrimitiveProxy(owner, "XorDrawPathANY",
                                        DrawPath.methodSignature,
                                        DrawPath.primTypeID,
                                        SurfaceType.AnyColor,
                                        CompositeType.Xor,
                                        SurfaceType.Any),
            new  GraphicsPrimitiveProxy(owner, "XorDrawRectANY",
                                        DrawRect.methodSignature,
                                        DrawRect.primTypeID,
                                        SurfaceType.AnyColor,
                                        CompositeType.Xor,
                                        SurfaceType.Any),
            new  GraphicsPrimitiveProxy(owner, "XorDrawGlyphListANY",
                                        DrawGlyphList.methodSignature,
                                        DrawGlyphList.primTypeID,
                                        SurfaceType.AnyColor,
                                        CompositeType.Xor,
                                        SurfaceType.Any),
            new  GraphicsPrimitiveProxy(owner, "XorDrawGlyphListAAANY",
                                        DrawGlyphListAA.methodSignature,
                                        DrawGlyphListAA.primTypeID,
                                        SurfaceType.AnyColor,
                                        CompositeType.Xor,
                                        SurfaceType.Any),
        };
        GraphicsPrimitiveMgr.register(primitives);
    }

    static void doDrawPoly(SurfaceData sData, PixelWriter pw,
                           int xPoints[], int yPoints[], int off, int nPoints,
                           Region clip, int transx, int transy, boolean close)
    {
        int mx, my, x1, y1;
        int[] tmp = null;
        mx = x1 = xPoints[off] + transx;
        my = y1 = yPoints[off] + transy;
        while (--nPoints > 0) {
            ++off;
            int x2 = xPoints[off] + transx;
            int y2 = yPoints[off] + transy;
            tmp = GeneralRenderer.doDrawLine(sData, pw, tmp, clip,
                                             x1, y1, x2, y2);
            x1 = x2;
            y1 = y2;
        }
        if (close && (x1 != mx || y1 != my)) {
            tmp = GeneralRenderer.doDrawLine(sData, pw, tmp, clip,
                                             x1, y1, mx, my);
        }
    }

    static void doSetRect(SurfaceData sData, PixelWriter pw,
                          int x1, int y1, int x2, int y2) {
        WritableRaster dstRast =
            (WritableRaster) sData.getRaster(x1, y1, x2-x1, y2-y1);
        pw.setRaster(dstRast);

        while (y1 < y2) {
            for (int x = x1; x < x2; x++) {
                pw.writePixel(x, y1);
            }
            y1++;
        }
    }

    static int[] doDrawLine(SurfaceData sData, PixelWriter pw, int[] boundPts,
                            Region clip,
                            int origx1, int origy1, int origx2, int origy2)
    {
        if (boundPts == null) {
            boundPts = new int[8];
        }
        boundPts[0] = origx1;
        boundPts[1] = origy1;
        boundPts[2] = origx2;
        boundPts[3] = origy2;
        if (!adjustLine(boundPts,
                        clip.getLoX(), clip.getLoY(),
                        clip.getHiX(), clip.getHiY()))
        {
            return boundPts;
        }
        int x1 = boundPts[0];
        int y1 = boundPts[1];
        int x2 = boundPts[2];
        int y2 = boundPts[3];

        WritableRaster dstRast = (WritableRaster)
            sData.getRaster(Math.min(x1, x2), Math.min(y1, y2),
                            Math.abs(x1 - x2) + 1, Math.abs(y1 - y2) + 1);
        pw.setRaster(dstRast);

        /* this could be made smaller, more elegant, more traditional. */
        if (x1 == x2) {
            if (y1 > y2) {
                do {
                    pw.writePixel(x1, y1);
                    y1--;
                } while (y1 >= y2);
            } else {
                do {
                    pw.writePixel(x1, y1);
                    y1++;
                } while (y1 <= y2);
            }
        } else if (y1 == y2) {
            if (x1 > x2) {
                do {
                    pw.writePixel(x1, y1);
                    x1--;
                } while (x1 >= x2);
            } else {
                do {
                    pw.writePixel(x1, y1);
                    x1++;
                } while (x1 <= x2);
            }
        } else {
            int dx = boundPts[4];
            int dy = boundPts[5];
            int ax = boundPts[6];
            int ay = boundPts[7];
            int steps;
            int bumpmajor;
            int bumpminor;
            int errminor;
            int errmajor;
            int error;
            boolean xmajor;

            if (ax >= ay) {
                /* x is dominant */
                xmajor = true;
                errmajor = ay * 2;
                errminor = ax * 2;
                bumpmajor = (dx < 0) ? -1 : 1;
                bumpminor = (dy < 0) ? -1 : 1;
                ax = -ax; /* For clipping adjustment below */
                steps = x2 - x1;
            } else {
                /* y is dominant */
                xmajor = false;
                errmajor = ax * 2;
                errminor = ay * 2;
                bumpmajor = (dy < 0) ? -1 : 1;
                bumpminor = (dx < 0) ? -1 : 1;
                ay = -ay; /* For clipping adjustment below */
                steps = y2 - y1;
            }
            error = - (errminor / 2);
            if (y1 != origy1) {
                int ysteps = y1 - origy1;
                if (ysteps < 0) {
                    ysteps = -ysteps;
                }
                error += ysteps * ax * 2;
            }
            if (x1 != origx1) {
                int xsteps = x1 - origx1;
                if (xsteps < 0) {
                    xsteps = -xsteps;
                }
                error += xsteps * ay * 2;
            }
            if (steps < 0) {
                steps = -steps;
            }
            if (xmajor) {
                do {
                    pw.writePixel(x1, y1);
                    x1 += bumpmajor;
                    error += errmajor;
                    if (error >= 0) {
                        y1 += bumpminor;
                        error -= errminor;
                    }
                } while (--steps >= 0);
            } else {
                do {
                    pw.writePixel(x1, y1);
                    y1 += bumpmajor;
                    error += errmajor;
                    if (error >= 0) {
                        x1 += bumpminor;
                        error -= errminor;
                    }
                } while (--steps >= 0);
            }
        }
        return boundPts;
    }

    public static void doDrawRect(PixelWriter pw,
                                  SunGraphics2D sg2d, SurfaceData sData,
                                  int x, int y, int w, int h)
    {
        if (w < 0 || h < 0) {
            return;
        }
        int x2 = Region.dimAdd(Region.dimAdd(x, w), 1);
        int y2 = Region.dimAdd(Region.dimAdd(y, h), 1);
        Region r = sg2d.getCompClip().getBoundsIntersectionXYXY(x, y, x2, y2);
        if (r.isEmpty()) {
            return;
        }
        int cx1 = r.getLoX();
        int cy1 = r.getLoY();
        int cx2 = r.getHiX();
        int cy2 = r.getHiY();

        if (w < 2 || h < 2) {
            doSetRect(sData, pw, cx1, cy1, cx2, cy2);
            return;
        }


        if (cy1 == y) {
            doSetRect(sData, pw,   cx1,   cy1,   cx2, cy1+1);
        }
        if (cx1 == x) {
            doSetRect(sData, pw,   cx1, cy1+1, cx1+1, cy2-1);
        }
        if (cx2 == x2) {
            doSetRect(sData, pw, cx2-1, cy1+1,   cx2, cy2-1);
        }
        if (cy2 == y2) {
            doSetRect(sData, pw,   cx1, cy2-1,   cx2,   cy2);
        }
    }

    /*
     * REMIND: For now this will field both AA and non-AA requests and
     * use a simple threshold to choose pixels if the supplied grey
     * bits are antialiased.  We should really find a way to disable
     * AA text at a higher level or to have the GlyphList be able to
     * reset the glyphs to non-AA after construction.
     */
    static void doDrawGlyphList(SurfaceData sData, PixelWriter pw,
                                GlyphList gl, Region clip)
    {
        int[] bounds = gl.getBounds();
        clip.clipBoxToBounds(bounds);
        int cx1 = bounds[0];
        int cy1 = bounds[1];
        int cx2 = bounds[2];
        int cy2 = bounds[3];

        WritableRaster dstRast =
            (WritableRaster) sData.getRaster(cx1, cy1, cx2 - cx1, cy2 - cy1);
        pw.setRaster(dstRast);

        int num = gl.getNumGlyphs();
        for (int i = 0; i < num; i++) {
            gl.setGlyphIndex(i);
            int metrics[] = gl.getMetrics();
            int gx1 = metrics[0];
            int gy1 = metrics[1];
            int w = metrics[2];
            int gx2 = gx1 + w;
            int gy2 = gy1 + metrics[3];
            int off = 0;
            if (gx1 < cx1) {
                off = cx1 - gx1;
                gx1 = cx1;
            }
            if (gy1 < cy1) {
                off += (cy1 - gy1) * w;
                gy1 = cy1;
            }
            if (gx2 > cx2) gx2 = cx2;
            if (gy2 > cy2) gy2 = cy2;
            if (gx2 > gx1 && gy2 > gy1) {
                byte alpha[] = gl.getGrayBits();
                w -= (gx2 - gx1);
                for (int y = gy1; y < gy2; y++) {
                    for (int x = gx1; x < gx2; x++) {
                        if (alpha[off++] < 0) {
                            pw.writePixel(x, y);
                        }
                    }
                    off += w;
                }
            }
        }
    }

    static final int OUTCODE_TOP     = 1;
    static final int OUTCODE_BOTTOM  = 2;
    static final int OUTCODE_LEFT    = 4;
    static final int OUTCODE_RIGHT   = 8;

    static int outcode(int x, int y, int xmin, int ymin, int xmax, int ymax) {
        int code;
        if (y < ymin) {
            code = OUTCODE_TOP;
        } else if (y > ymax) {
            code = OUTCODE_BOTTOM;
        } else {
            code = 0;
        }
        if (x < xmin) {
            code |= OUTCODE_LEFT;
        } else if (x > xmax) {
            code |= OUTCODE_RIGHT;
        }
        return code;
    }

    public static boolean adjustLine(int [] boundPts,
                                     int cxmin, int cymin, int cx2, int cy2)
    {
        int cxmax = cx2 - 1;
        int cymax = cy2 - 1;
        int x1 = boundPts[0];
        int y1 = boundPts[1];
        int x2 = boundPts[2];
        int y2 = boundPts[3];

        if ((cxmax < cxmin) || (cymax < cymin)) {
            return false;
        }

        if (x1 == x2) {
            if (x1 < cxmin || x1 > cxmax) {
                return false;
            }
            if (y1 > y2) {
                int t = y1;
                y1 = y2;
                y2 = t;
            }
            if (y1 < cymin) {
                y1 = cymin;
            }
            if (y2 > cymax) {
                y2 = cymax;
            }
            if (y1 > y2) {
                return false;
            }
            boundPts[1] = y1;
            boundPts[3] = y2;
        } else if (y1 == y2) {
            if (y1 < cymin || y1 > cymax) {
                return false;
            }
            if (x1 > x2) {
                int t = x1;
                x1 = x2;
                x2 = t;
            }
            if (x1 < cxmin) {
                x1 = cxmin;
            }
            if (x2 > cxmax) {
                x2 = cxmax;
            }
            if (x1 > x2) {
                return false;
            }
            boundPts[0] = x1;
            boundPts[2] = x2;
        } else {
            /* REMIND: This could overflow... */
            int outcode1, outcode2;
            int dx = x2 - x1;
            int dy = y2 - y1;
            int ax = (dx < 0) ? -dx : dx;
            int ay = (dy < 0) ? -dy : dy;
            boolean xmajor = (ax >= ay);

            outcode1 = outcode(x1, y1, cxmin, cymin, cxmax, cymax);
            outcode2 = outcode(x2, y2, cxmin, cymin, cxmax, cymax);
            while ((outcode1 | outcode2) != 0) {
                int xsteps, ysteps;
                if ((outcode1 & outcode2) != 0) {
                    return false;
                }
                if (outcode1 != 0) {
                    if (0 != (outcode1 & (OUTCODE_TOP | OUTCODE_BOTTOM))) {
                        if (0 != (outcode1 & OUTCODE_TOP)) {
                            y1 = cymin;
                        } else {
                            y1 = cymax;
                        }
                        ysteps = y1 - boundPts[1];
                        if (ysteps < 0) {
                            ysteps = -ysteps;
                        }
                        xsteps = 2 * ysteps * ax + ay;
                        if (xmajor) {
                            xsteps += ay - ax - 1;
                        }
                        xsteps = xsteps / (2 * ay);
                        if (dx < 0) {
                            xsteps = -xsteps;
                        }
                        x1 = boundPts[0] + xsteps;
                    } else if (0 !=
                               (outcode1 & (OUTCODE_LEFT | OUTCODE_RIGHT))) {
                        if (0 != (outcode1 & OUTCODE_LEFT)) {
                            x1 = cxmin;
                        } else {
                            x1 = cxmax;
                        }
                        xsteps = x1 - boundPts[0];
                        if (xsteps < 0) {
                            xsteps = -xsteps;
                        }
                        ysteps = 2 * xsteps * ay + ax;
                        if (!xmajor) {
                            ysteps += ax - ay - 1;
                        }
                        ysteps = ysteps / (2 * ax);
                        if (dy < 0) {
                            ysteps = -ysteps;
                        }
                        y1 = boundPts[1] + ysteps;
                    }
                    outcode1 = outcode(x1, y1, cxmin, cymin, cxmax, cymax);
                } else {
                    if (0 != (outcode2 & (OUTCODE_TOP | OUTCODE_BOTTOM))) {
                        if (0 != (outcode2 & OUTCODE_TOP)) {
                            y2 = cymin;
                        } else {
                            y2 = cymax;
                        }
                        ysteps = y2 - boundPts[3];
                        if (ysteps < 0) {
                            ysteps = -ysteps;
                        }
                        xsteps = 2 * ysteps * ax + ay;
                        if (xmajor) {
                            xsteps += ay - ax;
                        } else {
                            xsteps -= 1;
                        }
                        xsteps = xsteps / (2 * ay);
                        if (dx > 0) {
                            xsteps = -xsteps;
                        }
                        x2 = boundPts[2] + xsteps;
                    } else if (0 !=
                               (outcode2 & (OUTCODE_LEFT | OUTCODE_RIGHT))) {
                        if (0 != (outcode2 & OUTCODE_LEFT)) {
                            x2 = cxmin;
                        } else {
                            x2 = cxmax;
                        }
                        xsteps = x2 - boundPts[2];
                        if (xsteps < 0) {
                            xsteps = -xsteps;
                        }
                        ysteps = 2 * xsteps * ay + ax;
                        if (xmajor) {
                            ysteps -= 1;
                        } else {
                            ysteps += ax - ay;
                        }
                        ysteps = ysteps / (2 * ax);
                        if (dy > 0) {
                            ysteps = -ysteps;
                        }
                        y2 = boundPts[3] + ysteps;
                    }
                    outcode2 = outcode(x2, y2, cxmin, cymin, cxmax, cymax);
                }
            }
            boundPts[0] = x1;
            boundPts[1] = y1;
            boundPts[2] = x2;
            boundPts[3] = y2;
            boundPts[4] = dx;
            boundPts[5] = dy;
            boundPts[6] = ax;
            boundPts[7] = ay;
        }
        return true;
    }

    static PixelWriter createSolidPixelWriter(SunGraphics2D sg2d,
                                              SurfaceData sData)
    {
        ColorModel dstCM = sData.getColorModel();
        Object srcPixel = dstCM.getDataElements(sg2d.eargb, null);

        return new SolidPixelWriter(srcPixel);
    }

    static PixelWriter createXorPixelWriter(SunGraphics2D sg2d,
                                            SurfaceData sData)
    {
        ColorModel dstCM = sData.getColorModel();

        Object srcPixel = dstCM.getDataElements(sg2d.eargb, null);

        XORComposite comp = (XORComposite)sg2d.getComposite();
        int xorrgb = comp.getXorColor().getRGB();
        Object xorPixel = dstCM.getDataElements(xorrgb, null);

        switch (dstCM.getTransferType()) {
        case DataBuffer.TYPE_BYTE:
            return new XorPixelWriter.ByteData(srcPixel, xorPixel);
        case DataBuffer.TYPE_SHORT:
        case DataBuffer.TYPE_USHORT:
            return new XorPixelWriter.ShortData(srcPixel, xorPixel);
        case DataBuffer.TYPE_INT:
            return new XorPixelWriter.IntData(srcPixel, xorPixel);
        case DataBuffer.TYPE_FLOAT:
            return new XorPixelWriter.FloatData(srcPixel, xorPixel);
        case DataBuffer.TYPE_DOUBLE:
            return new XorPixelWriter.DoubleData(srcPixel, xorPixel);
        default:
            throw new InternalError("Unsupported XOR pixel type");
        }
    }
}

class SetFillRectANY extends FillRect {
    SetFillRectANY() {
        super(SurfaceType.AnyColor,
              CompositeType.SrcNoEa,
              SurfaceType.Any);
    }

    public void FillRect(SunGraphics2D sg2d, SurfaceData sData,
                         int x, int y, int w, int h)
    {
        PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);

        Region r = sg2d.getCompClip().getBoundsIntersectionXYWH(x, y, w, h);

        GeneralRenderer.doSetRect(sData, pw,
                                  r.getLoX(), r.getLoY(),
                                  r.getHiX(), r.getHiY());
    }
}

class PixelWriterDrawHandler extends ProcessPath.DrawHandler {
    PixelWriter pw;
    SurfaceData sData;
    Region clip;

    public PixelWriterDrawHandler(SurfaceData sData, PixelWriter pw,
                                  Region clip, int strokeHint) {
        super(clip.getLoX(), clip.getLoY(),
              clip.getHiX(), clip.getHiY(),
              strokeHint);
        this.sData = sData;
        this.pw = pw;
        this.clip = clip;
    }

    public void drawLine(int x0, int y0, int x1, int y1) {
        GeneralRenderer.doDrawLine(sData, pw, null, clip,
                                   x0, y0, x1, y1);
    }

    public void drawPixel(int x0, int y0) {
        GeneralRenderer.doSetRect(sData, pw, x0, y0, x0 + 1, y0 + 1);
    }

    public void drawScanline(int x0, int x1, int y0) {
        GeneralRenderer.doSetRect(sData, pw, x0, y0, x1 + 1, y0 + 1);
    }
}

class SetFillPathANY extends FillPath {
    SetFillPathANY() {
        super(SurfaceType.AnyColor, CompositeType.SrcNoEa,
              SurfaceType.Any);
    }

    public void FillPath(SunGraphics2D sg2d, SurfaceData sData,
                         int transx, int transy,
                         Path2D.Float p2df)
    {
        PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);
        ProcessPath.fillPath(
            new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(),
                                       sg2d.strokeHint),
            p2df, transx, transy);
    }
}

class SetFillSpansANY extends FillSpans {
    SetFillSpansANY() {
        super(SurfaceType.AnyColor,
              CompositeType.SrcNoEa,
              SurfaceType.Any);
    }

    public void FillSpans(SunGraphics2D sg2d, SurfaceData sData,
                          SpanIterator si)
    {
        PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);

        int span[] = new int[4];
        while (si.nextSpan(span)) {
            GeneralRenderer.doSetRect(sData, pw,
                                      span[0], span[1], span[2], span[3]);
        }
    }
}

class SetDrawLineANY extends DrawLine {
    SetDrawLineANY() {
        super(SurfaceType.AnyColor,
              CompositeType.SrcNoEa,
              SurfaceType.Any);
    }

    public void DrawLine(SunGraphics2D sg2d, SurfaceData sData,
                         int x1, int y1, int x2, int y2)
    {
        PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);

        if (y1 >= y2) {
            GeneralRenderer.doDrawLine(sData, pw, null,
                                       sg2d.getCompClip(),
                                       x2, y2, x1, y1);
        } else {
            GeneralRenderer.doDrawLine(sData, pw, null,
                                       sg2d.getCompClip(),
                                       x1, y1, x2, y2);
        }
    }
}

class SetDrawPolygonsANY extends DrawPolygons {
    SetDrawPolygonsANY() {
        super(SurfaceType.AnyColor,
              CompositeType.SrcNoEa,
              SurfaceType.Any);
    }

    public void DrawPolygons(SunGraphics2D sg2d, SurfaceData sData,
                             int xPoints[], int yPoints[],
                             int nPoints[], int numPolys,
                             int transx, int transy,
                             boolean close)
    {
        PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);

        int off = 0;
        Region clip = sg2d.getCompClip();
        for (int i = 0; i < numPolys; i++) {
            int numpts = nPoints[i];
            GeneralRenderer.doDrawPoly(sData, pw,
                                       xPoints, yPoints, off, numpts,
                                       clip, transx, transy, close);
            off += numpts;
        }
    }
}

class SetDrawPathANY extends DrawPath {
    SetDrawPathANY() {
        super(SurfaceType.AnyColor,
              CompositeType.SrcNoEa,
              SurfaceType.Any);
    }

    public void DrawPath(SunGraphics2D sg2d, SurfaceData sData,
                         int transx, int transy,
                         Path2D.Float p2df)
    {
        PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);
        ProcessPath.drawPath(
            new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(),
                                       sg2d.strokeHint),
            p2df, transx, transy
        );
    }
}

class SetDrawRectANY extends DrawRect {
    SetDrawRectANY() {
        super(SurfaceType.AnyColor,
              CompositeType.SrcNoEa,
              SurfaceType.Any);
    }

    public void DrawRect(SunGraphics2D sg2d, SurfaceData sData,
                         int x, int y, int w, int h)
    {
        PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData);

        GeneralRenderer.doDrawRect(pw, sg2d, sData, x, y, w, h);
    }
}

class XorFillRectANY extends FillRect {
    XorFillRectANY() {
        super(SurfaceType.AnyColor,
              CompositeType.Xor,
              SurfaceType.Any);
    }

    public void FillRect(SunGraphics2D sg2d, SurfaceData sData,
                            int x, int y, int w, int h)
    {
        PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);

        Region r = sg2d.getCompClip().getBoundsIntersectionXYWH(x, y, w, h);

        GeneralRenderer.doSetRect(sData, pw,
                                  r.getLoX(), r.getLoY(),
                                  r.getHiX(), r.getHiY());
    }
}

class XorFillPathANY extends FillPath {
    XorFillPathANY() {
        super(SurfaceType.AnyColor, CompositeType.Xor,
              SurfaceType.Any);
    }

    public void FillPath(SunGraphics2D sg2d, SurfaceData sData,
                         int transx, int transy,
                         Path2D.Float p2df)
    {
        PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);
        ProcessPath.fillPath(
            new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(),
                                       sg2d.strokeHint),
            p2df, transx, transy);
    }
}

class XorFillSpansANY extends FillSpans {
    XorFillSpansANY() {
        super(SurfaceType.AnyColor,
              CompositeType.Xor,
              SurfaceType.Any);
    }

    public void FillSpans(SunGraphics2D sg2d, SurfaceData sData,
                          SpanIterator si)
    {
        PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);

        int span[] = new int[4];
        while (si.nextSpan(span)) {
            GeneralRenderer.doSetRect(sData, pw,
                                      span[0], span[1], span[2], span[3]);
        }
    }
}

class XorDrawLineANY extends DrawLine {
    XorDrawLineANY() {
        super(SurfaceType.AnyColor,
              CompositeType.Xor,
              SurfaceType.Any);
    }

    public void DrawLine(SunGraphics2D sg2d, SurfaceData sData,
                         int x1, int y1, int x2, int y2)
    {
        PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);

        if (y1 >= y2) {
            GeneralRenderer.doDrawLine(sData, pw, null,
                                       sg2d.getCompClip(),
                                       x2, y2, x1, y1);
        } else {
            GeneralRenderer.doDrawLine(sData, pw, null,
                                       sg2d.getCompClip(),
                                       x1, y1, x2, y2);
        }
    }
}

class XorDrawPolygonsANY extends DrawPolygons {
    XorDrawPolygonsANY() {
        super(SurfaceType.AnyColor,
              CompositeType.Xor,
              SurfaceType.Any);
    }

    public void DrawPolygons(SunGraphics2D sg2d, SurfaceData sData,
                             int xPoints[], int yPoints[],
                             int nPoints[], int numPolys,
                             int transx, int transy,
                             boolean close)
    {
        PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);

        int off = 0;
        Region clip = sg2d.getCompClip();
        for (int i = 0; i < numPolys; i++) {
            int numpts = nPoints[i];
            GeneralRenderer.doDrawPoly(sData, pw,
                                       xPoints, yPoints, off, numpts,
                                       clip, transx, transy, close);
            off += numpts;
        }
    }
}

class XorDrawPathANY extends DrawPath {
    XorDrawPathANY() {
        super(SurfaceType.AnyColor,
              CompositeType.Xor,
              SurfaceType.Any);
    }

    public void DrawPath(SunGraphics2D sg2d, SurfaceData sData,
                         int transx, int transy, Path2D.Float p2df)
    {
        PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);
        ProcessPath.drawPath(
            new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(),
                                       sg2d.strokeHint),
            p2df, transx, transy
        );
    }
}

class XorDrawRectANY extends DrawRect {
    XorDrawRectANY() {
        super(SurfaceType.AnyColor,
              CompositeType.Xor,
              SurfaceType.Any);
    }

    public void DrawRect(SunGraphics2D sg2d, SurfaceData sData,
                         int x, int y, int w, int h)
    {
        PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);

        GeneralRenderer.doDrawRect(pw, sg2d, sData, x, y, w, h);
    }
}

class XorDrawGlyphListANY extends DrawGlyphList {
    XorDrawGlyphListANY() {
        super(SurfaceType.AnyColor,
              CompositeType.Xor,
              SurfaceType.Any);
    }

    public void DrawGlyphList(SunGraphics2D sg2d, SurfaceData sData,
                              GlyphList gl)
    {
        PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);
        GeneralRenderer.doDrawGlyphList(sData, pw, gl, sg2d.getCompClip());
    }
}

class XorDrawGlyphListAAANY extends DrawGlyphListAA {
    XorDrawGlyphListAAANY() {
        super(SurfaceType.AnyColor,
              CompositeType.Xor,
              SurfaceType.Any);
    }

    public void DrawGlyphListAA(SunGraphics2D sg2d, SurfaceData sData,
                                GlyphList gl)
    {
        PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData);
        GeneralRenderer.doDrawGlyphList(sData, pw, gl, sg2d.getCompClip());
    }
}

abstract class PixelWriter {
    protected WritableRaster dstRast;

    public void setRaster(WritableRaster dstRast) {
        this.dstRast = dstRast;
    }

    public abstract void writePixel(int x, int y);
}

class SolidPixelWriter extends PixelWriter {
    protected Object srcData;

    SolidPixelWriter(Object srcPixel) {
        this.srcData = srcPixel;
    }

    public void writePixel(int x, int y) {
        dstRast.setDataElements(x, y, srcData);
    }
}

abstract class XorPixelWriter extends PixelWriter {
    protected ColorModel dstCM;

    public void writePixel(int x, int y) {
        Object dstPixel = dstRast.getDataElements(x, y, null);
        xorPixel(dstPixel);
        dstRast.setDataElements(x, y, dstPixel);
    }

    protected abstract void xorPixel(Object pixData);

    public static class ByteData extends XorPixelWriter {
        byte[] xorData;

        ByteData(Object srcPixel, Object xorPixel) {
            this.xorData = (byte[]) srcPixel;
            xorPixel(xorPixel);
            this.xorData = (byte[]) xorPixel;
        }

        protected void xorPixel(Object pixData) {
            byte[] dstData = (byte[]) pixData;
            for (int i = 0; i < dstData.length; i++) {
                dstData[i] ^= xorData[i];
            }
        }
    }

    public static class ShortData extends XorPixelWriter {
        short[] xorData;

        ShortData(Object srcPixel, Object xorPixel) {
            this.xorData = (short[]) srcPixel;
            xorPixel(xorPixel);
            this.xorData = (short[]) xorPixel;
        }

        protected void xorPixel(Object pixData) {
            short[] dstData = (short[]) pixData;
            for (int i = 0; i < dstData.length; i++) {
                dstData[i] ^= xorData[i];
            }
        }
    }

    public static class IntData extends XorPixelWriter {
        int[] xorData;

        IntData(Object srcPixel, Object xorPixel) {
            this.xorData = (int[]) srcPixel;
            xorPixel(xorPixel);
            this.xorData = (int[]) xorPixel;
        }

        protected void xorPixel(Object pixData) {
            int[] dstData = (int[]) pixData;
            for (int i = 0; i < dstData.length; i++) {
                dstData[i] ^= xorData[i];
            }
        }
    }

    public static class FloatData extends XorPixelWriter {
        int[] xorData;

        FloatData(Object srcPixel, Object xorPixel) {
            float[] srcData = (float[]) srcPixel;
            float[] xorData = (float[]) xorPixel;
            this.xorData = new int[srcData.length];
            for (int i = 0; i < srcData.length; i++) {
                this.xorData[i] = (Float.floatToIntBits(srcData[i]) ^
                                   Float.floatToIntBits(xorData[i]));
            }
        }

        protected void xorPixel(Object pixData) {
            float[] dstData = (float[]) pixData;
            for (int i = 0; i < dstData.length; i++) {
                int v = Float.floatToIntBits(dstData[i]) ^ xorData[i];
                dstData[i] = Float.intBitsToFloat(v);
            }
        }
    }

    public static class DoubleData extends XorPixelWriter {
        long[] xorData;

        DoubleData(Object srcPixel, Object xorPixel) {
            double[] srcData = (double[]) srcPixel;
            double[] xorData = (double[]) xorPixel;
            this.xorData = new long[srcData.length];
            for (int i = 0; i < srcData.length; i++) {
                this.xorData[i] = (Double.doubleToLongBits(srcData[i]) ^
                                   Double.doubleToLongBits(xorData[i]));
            }
        }

        protected void xorPixel(Object pixData) {
            double[] dstData = (double[]) pixData;
            for (int i = 0; i < dstData.length; i++) {
                long v = Double.doubleToLongBits(dstData[i]) ^ xorData[i];
                dstData[i] = Double.longBitsToDouble(v);
            }
        }
    }
}
