/*
 * Copyright (c) 1999, 2024, 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.Color;
import java.awt.Rectangle;
import java.awt.Transparency;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.Raster;

import sun.font.FontUtilities;
import sun.java2d.loops.RenderCache;
import sun.java2d.loops.RenderLoops;
import sun.java2d.loops.CompositeType;
import sun.java2d.loops.SurfaceType;
import sun.java2d.loops.MaskFill;
import sun.java2d.loops.DrawLine;
import sun.java2d.loops.FillRect;
import sun.java2d.loops.DrawRect;
import sun.java2d.loops.DrawPolygons;
import sun.java2d.loops.DrawPath;
import sun.java2d.loops.FillPath;
import sun.java2d.loops.FillSpans;
import sun.java2d.loops.FillParallelogram;
import sun.java2d.loops.DrawParallelogram;
import sun.java2d.loops.FontInfo;
import sun.java2d.loops.DrawGlyphList;
import sun.java2d.loops.DrawGlyphListAA;
import sun.java2d.loops.DrawGlyphListLCD;
import sun.java2d.loops.DrawGlyphListColor;
import sun.java2d.pipe.LoopPipe;
import sun.java2d.pipe.ShapeDrawPipe;
import sun.java2d.pipe.ParallelogramPipe;
import sun.java2d.pipe.CompositePipe;
import sun.java2d.pipe.GeneralCompositePipe;
import sun.java2d.pipe.SpanClipRenderer;
import sun.java2d.pipe.SpanShapeRenderer;
import sun.java2d.pipe.AAShapePipe;
import sun.java2d.pipe.AlphaPaintPipe;
import sun.java2d.pipe.AlphaColorPipe;
import sun.java2d.pipe.PixelToShapeConverter;
import sun.java2d.pipe.PixelToParallelogramConverter;
import sun.java2d.pipe.TextPipe;
import sun.java2d.pipe.TextRenderer;
import sun.java2d.pipe.AATextRenderer;
import sun.java2d.pipe.LCDTextRenderer;
import sun.java2d.pipe.SolidTextRenderer;
import sun.java2d.pipe.OutlineTextRenderer;
import sun.java2d.pipe.DrawImagePipe;
import sun.java2d.pipe.DrawImage;
import sun.awt.SunHints;
import sun.awt.image.SurfaceManager;
import sun.java2d.pipe.LoopBasedPipe;

/**
 * This class provides various pieces of information relevant to a
 * particular drawing surface.  The information obtained from this
 * object describes the pixels of a particular instance of a drawing
 * surface and can only be shared among the various graphics objects
 * that target the same BufferedImage or the same screen Component.
 * <p>
 * Each SurfaceData object holds a StateTrackableDelegate object
 * which tracks both changes to the content of the pixels of this
 * surface and changes to the overall state of the pixels - such
 * as becoming invalid or losing the surface.  The delegate is
 * marked "dirty" whenever the setSurfaceLost() or invalidate()
 * methods are called and should also be marked "dirty" by the
 * rendering pipelines whenever they modify the pixels of this
 * SurfaceData.
 * <p>
 * If you get a StateTracker from a SurfaceData and it reports
 * that it is still "current", then you can trust that the pixels
 * have not changed and that the SurfaceData is still valid and
 * has not lost its underlying storage (surfaceLost) since you
 * retrieved the tracker.
 */
public abstract class SurfaceData
    implements Transparency, DisposerTarget, StateTrackable, Surface
{
    private long pData;
    private boolean valid;
    private boolean surfaceLost; // = false;
    private SurfaceType surfaceType;
    private ColorModel colorModel;

    private Object disposerReferent = new Object();

    private static native void initIDs();

    private SurfaceManager.ProxyCache blitProxyCache;
    private StateTrackableDelegate stateDelegate;

    static {
        initIDs();
    }

    protected SurfaceData(SurfaceType surfaceType, ColorModel cm) {
        this(State.STABLE, surfaceType, cm);
    }

    protected SurfaceData(State state, SurfaceType surfaceType, ColorModel cm) {
        this(StateTrackableDelegate.createInstance(state), surfaceType, cm);
    }

    protected SurfaceData(StateTrackableDelegate trackable,
                          SurfaceType surfaceType, ColorModel cm)
    {
        this.stateDelegate = trackable;
        this.colorModel = cm;
        this.surfaceType = surfaceType;
        valid = true;
    }

    protected SurfaceData(State state) {
        this.stateDelegate = StateTrackableDelegate.createInstance(state);
        valid = true;
    }

    /**
     * Subclasses can set a "blit proxy cache" which will be used
     * along with the SurfaceManager to
     * store acceleration-compatible cached copies of source images.
     * The getSourceSurfaceData() method uses this cache to manage
     * copies of a source image as described below.
     * <p>
     * The cache used should be as unique as it needs
     * to be to ensure that multiple acceleratible destinations can
     * each store their cached copies separately into different caches
     * without interfering with each other or getting back the wrong
     * cached copy.
     * <p>
     * Many GraphicsConfiguration implementations have their own
     * cache as the GC object is
     * typically unique to a given screen and pixel format, but
     * other rendering destinations may have more or less stringent
     * sharing requirements.  For instance, X11 pixmaps can be
     * shared on a given screen by any GraphicsConfiguration that
     * has the same depth and SurfaceType.  Multiple such GCs with
     * the same depth and SurfaceType can exist per screen so storing
     * a different cached proxy for each would be a waste.  One can
     * imagine platforms where a single cached copy can be created
     * and shared across all screens and pixel formats - such
     * implementations could use a single heavily shared cache object.
     */
    protected void setBlitProxyCache(SurfaceManager.ProxyCache cache) {
        // Caching is effectively disabled if we never have a proxy cache
        // since the getSourceSurfaceData() method only does caching
        // if the cache is not null.
        if (SurfaceDataProxy.isCachingAllowed()) {
            this.blitProxyCache = cache;
        }
    }

    /**
     * This method is called on a destination SurfaceData to choose
     * the best SurfaceData from a source Image for an imaging
     * operation, with help from its SurfaceManager.
     * The method may determine that the default SurfaceData was
     * really the best choice in the first place, or it may decide
     * to use a cached surface.  Some general decisions about whether
     * acceleration is enabled are made by this method, but any
     * decision based on the type of the source image is made in
     * the makeProxyFor method below when it comes up with the
     * appropriate SurfaceDataProxy instance.
     * The parameters describe the type of imaging operation being performed.
     * <p>
     * If a blitProxyCache was supplied by the subclass then it is
     * used to potentially override the choice of source SurfaceData.
     * The outline of this process is:
     * <ol>
     * <li> Image pipeline asks destSD to find an appropriate
     *      srcSD for a given source Image object.
     * <li> destSD gets the SurfaceManager of the source Image
     *      and first retrieves the default SD from it using
     *      getPrimarySurfaceData()
     * <li> destSD uses its "blit proxy cache" (if set) to look for
     *      some cached data corresponding to the the source SurfaceManager
     * <li> If the cached data is null then makeProxyFor() is used
     *      to create some cached data which is stored back in the
     *      source SurfaceManager under the same key for future uses.
     * <li> The cached data will be a SurfaceDataProxy object.
     * <li> The SurfaceDataProxy object is then consulted to
     *      return a replacement SurfaceData object (typically
     *      a cached copy if appropriate, or the original if not).
     * </ol>
     */
    public SurfaceData getSourceSurfaceData(Image img,
                                            int txtype,
                                            CompositeType comp,
                                            Color bgColor)
    {
        SurfaceManager srcMgr = SurfaceManager.getManager(img);
        SurfaceData srcData = srcMgr.getPrimarySurfaceData();
        if (img.getAccelerationPriority() > 0.0f && blitProxyCache != null) {
            SurfaceDataProxy sdp = blitProxyCache.get(srcMgr);
            if (sdp == null || !sdp.isValid()) {
                if (srcData.getState() == State.UNTRACKABLE) {
                    sdp = SurfaceDataProxy.UNCACHED;
                } else {
                    sdp = makeProxyFor(srcData);
                }
                blitProxyCache.put(srcMgr, sdp);
            }
            srcData = sdp.replaceData(srcData, txtype, comp, bgColor);
        }
        return srcData;
    }

    /**
     * This method is called on a destination SurfaceData to choose
     * a proper SurfaceDataProxy subclass for a source SurfaceData
     * to use to control when and with what surface to override a
     * given image operation.  The argument is the default SurfaceData
     * for the source Image.
     * <p>
     * The type of the return object is chosen based on the
     * acceleration capabilities of this SurfaceData and the
     * type of the given source SurfaceData object.
     * <p>
     * In some cases the original SurfaceData will always be the
     * best choice to use to blit to this SurfaceData.  This can
     * happen if the source image is a hardware surface of the
     * same type as this one and so acceleration will happen without
     * any caching.  It may also be the case that the source image
     * can never be accelerated on this SurfaceData - for example
     * because it is translucent and there are no accelerated
     * translucent image ops for this surface.
     * <p>
     * In those cases there is a special SurfaceDataProxy.UNCACHED
     * instance that represents a NOP for caching purposes - it
     * always returns the original sourceSD object as the replacement
     * copy so no caching is ever performed.
     */
    public SurfaceDataProxy makeProxyFor(SurfaceData srcData) {
        return SurfaceDataProxy.UNCACHED;
    }

    /**
     * Extracts the SurfaceManager from the given Image, and then
     * returns the SurfaceData object that would best be suited as the
     * destination surface in some rendering operation.
     */
    public static SurfaceData getPrimarySurfaceData(Image img) {
        SurfaceManager sMgr = SurfaceManager.getManager(img);
        return sMgr.getPrimarySurfaceData();
    }

    /**
     * Restores the contents of the given Image and then returns the new
     * SurfaceData object in use by the Image's SurfaceManager.
     */
    public static SurfaceData restoreContents(Image img) {
        SurfaceManager sMgr = SurfaceManager.getManager(img);
        return sMgr.restoreContents();
    }

    public State getState() {
        return stateDelegate.getState();
    }

    public StateTracker getStateTracker() {
        return stateDelegate.getStateTracker();
    }

    /**
     * Marks this surface as dirty.
     */
    public final void markDirty() {
        stateDelegate.markDirty();
    }

    /**
     * Sets the value of the surfaceLost variable, which indicates whether
     * something has happened to the rendering surface such that it needs
     * to be restored and re-rendered.
     */
    public void setSurfaceLost(boolean lost) {
        surfaceLost = lost;
        stateDelegate.markDirty();
    }

    public boolean isSurfaceLost() {
        return surfaceLost;
    }

    /**
     * Returns a boolean indicating whether or not this SurfaceData is valid.
     */
    public final boolean isValid() {
        return valid;
    }

    public Object getDisposerReferent() {
        return disposerReferent;
    }

    public long getNativeOps() {
        return pData;
    }

    /**
     * Sets this SurfaceData object to the invalid state.  All Graphics
     * objects must get a new SurfaceData object via the refresh method
     * and revalidate their pipelines before continuing.
     */
    public void invalidate() {
        valid = false;
        stateDelegate.markDirty();
    }

    /**
     * Certain changes in the configuration of a surface require the
     * invalidation of existing associated SurfaceData objects and
     * the creation of brand new ones.  These changes include size,
     * ColorModel, or SurfaceType.  Existing Graphics objects
     * which are directed at such surfaces, however, must continue
     * to render to them even after the change occurs underneath
     * the covers.  The getReplacement() method is called from
     * SunGraphics2D.revalidateAll() when the associated SurfaceData
     * is found to be invalid so that a Graphics object can continue
     * to render to the surface in its new configuration.
     *
     * Such changes only tend to happen to window based surfaces since
     * most image based surfaces never change size or pixel format.
     * Even VolatileImage objects never change size and they only
     * change their pixel format when manually validated against a
     * new GraphicsConfiguration, at which point old Graphics objects
     * are no longer expected to render to them after the validation
     * step.  Thus, only window based surfaces really need to deal
     * with this form of replacement.
     */
    public abstract SurfaceData getReplacement();

    protected static final LoopPipe colorPrimitives;

    public static final TextPipe outlineTextRenderer;
    public static final TextPipe solidTextRenderer;
    public static final TextPipe aaTextRenderer;
    public static final TextPipe lcdTextRenderer;

    protected static final AlphaColorPipe colorPipe;
    protected static final PixelToShapeConverter colorViaShape;
    protected static final PixelToParallelogramConverter colorViaPgram;
    protected static final TextPipe colorText;
    protected static final CompositePipe clipColorPipe;
    protected static final TextPipe clipColorText;
    protected static final AAShapePipe AAColorShape;
    protected static final PixelToParallelogramConverter AAColorViaShape;
    protected static final PixelToParallelogramConverter AAColorViaPgram;
    protected static final AAShapePipe AAClipColorShape;
    protected static final PixelToParallelogramConverter AAClipColorViaShape;

    protected static final CompositePipe paintPipe;
    protected static final SpanShapeRenderer paintShape;
    protected static final PixelToShapeConverter paintViaShape;
    protected static final TextPipe paintText;
    protected static final CompositePipe clipPaintPipe;
    protected static final TextPipe clipPaintText;
    protected static final AAShapePipe AAPaintShape;
    protected static final PixelToParallelogramConverter AAPaintViaShape;
    protected static final AAShapePipe AAClipPaintShape;
    protected static final PixelToParallelogramConverter AAClipPaintViaShape;

    protected static final CompositePipe compPipe;
    protected static final SpanShapeRenderer compShape;
    protected static final PixelToShapeConverter compViaShape;
    protected static final TextPipe compText;
    protected static final CompositePipe clipCompPipe;
    protected static final TextPipe clipCompText;
    protected static final AAShapePipe AACompShape;
    protected static final PixelToParallelogramConverter AACompViaShape;
    protected static final AAShapePipe AAClipCompShape;
    protected static final PixelToParallelogramConverter AAClipCompViaShape;

    protected static final DrawImagePipe imagepipe;

    // Utility subclass to add the LoopBasedPipe tagging interface
    static class PixelToShapeLoopConverter
        extends PixelToShapeConverter
        implements LoopBasedPipe
    {
        public PixelToShapeLoopConverter(ShapeDrawPipe pipe) {
            super(pipe);
        }
    }

    // Utility subclass to add the LoopBasedPipe tagging interface
    static class PixelToPgramLoopConverter
        extends PixelToParallelogramConverter
        implements LoopBasedPipe
    {
        public PixelToPgramLoopConverter(ShapeDrawPipe shapepipe,
                                         ParallelogramPipe pgrampipe,
                                         double minPenSize,
                                         double normPosition,
                                         boolean adjustfill)
        {
            super(shapepipe, pgrampipe, minPenSize, normPosition, adjustfill);
        }
    }

    private static PixelToParallelogramConverter
        makeConverter(AAShapePipe renderer,
                      ParallelogramPipe pgrampipe)
    {
        return new PixelToParallelogramConverter(renderer,
                                                 pgrampipe,
                                                 1.0/8.0, 0.499,
                                                 false);
    }

    private static PixelToParallelogramConverter
        makeConverter(AAShapePipe renderer)
    {
        return makeConverter(renderer, renderer);
    }

    static {
        colorPrimitives = new LoopPipe();

        outlineTextRenderer = new OutlineTextRenderer();
        aaTextRenderer = new AATextRenderer();
        if (FontUtilities.isMacOSX14) {
            solidTextRenderer = aaTextRenderer;
        } else {
            solidTextRenderer = new SolidTextRenderer();
        }
        lcdTextRenderer = new LCDTextRenderer();

        colorPipe = new AlphaColorPipe();
        // colorShape = colorPrimitives;
        colorViaShape = new PixelToShapeLoopConverter(colorPrimitives);
        colorViaPgram = new PixelToPgramLoopConverter(colorPrimitives,
                                                      colorPrimitives,
                                                      1.0, 0.25, true);
        colorText = new TextRenderer(colorPipe);
        clipColorPipe = new SpanClipRenderer(colorPipe);
        clipColorText = new TextRenderer(clipColorPipe);
        AAColorShape = new AAShapePipe(colorPipe);
        AAColorViaShape = makeConverter(AAColorShape);
        AAColorViaPgram = makeConverter(AAColorShape, colorPipe);
        AAClipColorShape = new AAShapePipe(clipColorPipe);
        AAClipColorViaShape = makeConverter(AAClipColorShape);

        paintPipe = new AlphaPaintPipe();
        paintShape = new SpanShapeRenderer.Composite(paintPipe);
        paintViaShape = new PixelToShapeConverter(paintShape);
        paintText = new TextRenderer(paintPipe);
        clipPaintPipe = new SpanClipRenderer(paintPipe);
        clipPaintText = new TextRenderer(clipPaintPipe);
        AAPaintShape = new AAShapePipe(paintPipe);
        AAPaintViaShape = makeConverter(AAPaintShape);
        AAClipPaintShape = new AAShapePipe(clipPaintPipe);
        AAClipPaintViaShape = makeConverter(AAClipPaintShape);

        compPipe = new GeneralCompositePipe();
        compShape = new SpanShapeRenderer.Composite(compPipe);
        compViaShape = new PixelToShapeConverter(compShape);
        compText = new TextRenderer(compPipe);
        clipCompPipe = new SpanClipRenderer(compPipe);
        clipCompText = new TextRenderer(clipCompPipe);
        AACompShape = new AAShapePipe(compPipe);
        AACompViaShape = makeConverter(AACompShape);
        AAClipCompShape = new AAShapePipe(clipCompPipe);
        AAClipCompViaShape = makeConverter(AAClipCompShape);

        imagepipe = new DrawImage();
    }

    /* Not all surfaces and rendering mode combinations support LCD text. */
    static final int LOOP_UNKNOWN = 0;
    static final int LOOP_FOUND = 1;
    static final int LOOP_NOTFOUND = 2;
    int haveLCDLoop;
    int havePgramXORLoop;
    int havePgramSolidLoop;

    public boolean canRenderLCDText(SunGraphics2D sg2d) {
        // For now the answer can only be true in the following cases:
        if (sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY &&
            sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR &&
            sg2d.clipState <= SunGraphics2D.CLIP_RECTANGULAR &&
            sg2d.surfaceData.getTransparency() == Transparency.OPAQUE)
        {
            if (haveLCDLoop == LOOP_UNKNOWN) {
                DrawGlyphListLCD loop =
                    DrawGlyphListLCD.locate(SurfaceType.AnyColor,
                                            CompositeType.SrcNoEa,
                                            getSurfaceType());
                haveLCDLoop = (loop != null) ? LOOP_FOUND : LOOP_NOTFOUND;
            }
            return haveLCDLoop == LOOP_FOUND;
        }
        return false; /* for now - in the future we may want to search */
    }

    public boolean canRenderParallelograms(SunGraphics2D sg2d) {
        if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) {
            if (sg2d.compositeState == SunGraphics2D.COMP_XOR) {
                if (havePgramXORLoop == LOOP_UNKNOWN) {
                    FillParallelogram loop =
                        FillParallelogram.locate(SurfaceType.AnyColor,
                                                 CompositeType.Xor,
                                                 getSurfaceType());
                    havePgramXORLoop =
                        (loop != null) ? LOOP_FOUND : LOOP_NOTFOUND;
                }
                return havePgramXORLoop == LOOP_FOUND;
            } else if (sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY &&
                       sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON &&
                       sg2d.clipState != SunGraphics2D.CLIP_SHAPE)
            {
                if (havePgramSolidLoop == LOOP_UNKNOWN) {
                    FillParallelogram loop =
                        FillParallelogram.locate(SurfaceType.AnyColor,
                                                 CompositeType.SrcNoEa,
                                                 getSurfaceType());
                    havePgramSolidLoop =
                        (loop != null) ? LOOP_FOUND : LOOP_NOTFOUND;
                }
                return havePgramSolidLoop == LOOP_FOUND;
            }
        }
        return false;
    }

    public void validatePipe(SunGraphics2D sg2d) {
        sg2d.imagepipe = imagepipe;
        if (sg2d.compositeState == SunGraphics2D.COMP_XOR) {
            if (sg2d.paintState > SunGraphics2D.PAINT_ALPHACOLOR) {
                sg2d.drawpipe = paintViaShape;
                sg2d.fillpipe = paintViaShape;
                sg2d.shapepipe = paintShape;
                // REMIND: Ideally custom paint mode would use glyph
                // rendering as opposed to outline rendering but the
                // glyph paint rendering pipeline uses MaskBlit which
                // is not defined for XOR.  This means that text drawn
                // in XOR mode with a Color object is different than
                // text drawn in XOR mode with a Paint object.
                sg2d.textpipe = outlineTextRenderer;
            } else {
                PixelToShapeConverter converter;
                if (canRenderParallelograms(sg2d)) {
                    converter = colorViaPgram;
                    // Note that we use the transforming pipe here because it
                    // will examine the shape and possibly perform an optimized
                    // operation if it can be simplified.  The simplifications
                    // will be valid for all STROKE and TRANSFORM types.
                    sg2d.shapepipe = colorViaPgram;
                } else {
                    converter = colorViaShape;
                    sg2d.shapepipe = colorPrimitives;
                }
                if (sg2d.clipState == SunGraphics2D.CLIP_SHAPE) {
                    sg2d.drawpipe = converter;
                    sg2d.fillpipe = converter;
                    // REMIND: We should not be changing text strategies
                    // between outline and glyph rendering based upon the
                    // presence of a complex clip as that could cause a
                    // mismatch when drawing the same text both clipped
                    // and unclipped on two separate rendering passes.
                    // Unfortunately, all of the clipped glyph rendering
                    // pipelines rely on the use of the MaskBlit operation
                    // which is not defined for XOR.
                    sg2d.textpipe = outlineTextRenderer;
                } else {
                    if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
                        sg2d.drawpipe = converter;
                        sg2d.fillpipe = converter;
                    } else {
                        if (sg2d.strokeState != SunGraphics2D.STROKE_THIN) {
                            sg2d.drawpipe = converter;
                        } else {
                            sg2d.drawpipe = colorPrimitives;
                        }
                        sg2d.fillpipe = colorPrimitives;
                    }
                    sg2d.textpipe = solidTextRenderer;
                }
                // assert(sg2d.surfaceData == this);
            }
        } else if (sg2d.compositeState == SunGraphics2D.COMP_CUSTOM) {
            if (sg2d.antialiasHint == SunHints.INTVAL_ANTIALIAS_ON) {
                if (sg2d.clipState == SunGraphics2D.CLIP_SHAPE) {
                    sg2d.drawpipe = AAClipCompViaShape;
                    sg2d.fillpipe = AAClipCompViaShape;
                    sg2d.shapepipe = AAClipCompViaShape;
                    sg2d.textpipe = clipCompText;
                } else {
                    sg2d.drawpipe = AACompViaShape;
                    sg2d.fillpipe = AACompViaShape;
                    sg2d.shapepipe = AACompViaShape;
                    sg2d.textpipe = compText;
                }
            } else {
                sg2d.drawpipe = compViaShape;
                sg2d.fillpipe = compViaShape;
                sg2d.shapepipe = compShape;
                if (sg2d.clipState == SunGraphics2D.CLIP_SHAPE) {
                    sg2d.textpipe = clipCompText;
                } else {
                    sg2d.textpipe = compText;
                }
            }
        } else if (sg2d.antialiasHint == SunHints.INTVAL_ANTIALIAS_ON) {
            sg2d.alphafill = getMaskFill(sg2d);
            // assert(sg2d.surfaceData == this);
            if (sg2d.alphafill != null) {
                if (sg2d.clipState == SunGraphics2D.CLIP_SHAPE) {
                    sg2d.drawpipe = AAClipColorViaShape;
                    sg2d.fillpipe = AAClipColorViaShape;
                    sg2d.shapepipe = AAClipColorViaShape;
                    sg2d.textpipe = clipColorText;
                } else {
                    PixelToParallelogramConverter converter =
                        (sg2d.alphafill.canDoParallelograms()
                         ? AAColorViaPgram
                         : AAColorViaShape);
                    sg2d.drawpipe = converter;
                    sg2d.fillpipe = converter;
                    sg2d.shapepipe = converter;
                    if (sg2d.paintState > SunGraphics2D.PAINT_ALPHACOLOR ||
                        sg2d.compositeState > SunGraphics2D.COMP_ISCOPY)
                    {
                        sg2d.textpipe = colorText;
                    } else {
                        sg2d.textpipe = getTextPipe(sg2d, true /* AA==ON */);
                    }
                }
            } else {
                if (sg2d.clipState == SunGraphics2D.CLIP_SHAPE) {
                    sg2d.drawpipe = AAClipPaintViaShape;
                    sg2d.fillpipe = AAClipPaintViaShape;
                    sg2d.shapepipe = AAClipPaintViaShape;
                    sg2d.textpipe = clipPaintText;
                } else {
                    sg2d.drawpipe = AAPaintViaShape;
                    sg2d.fillpipe = AAPaintViaShape;
                    sg2d.shapepipe = AAPaintViaShape;
                    sg2d.textpipe = paintText;
                }
            }
        } else if (sg2d.paintState > SunGraphics2D.PAINT_ALPHACOLOR ||
                   sg2d.compositeState > SunGraphics2D.COMP_ISCOPY ||
                   sg2d.clipState == SunGraphics2D.CLIP_SHAPE)
        {
            sg2d.drawpipe = paintViaShape;
            sg2d.fillpipe = paintViaShape;
            sg2d.shapepipe = paintShape;
            sg2d.alphafill = getMaskFill(sg2d);
            // assert(sg2d.surfaceData == this);
            if (sg2d.alphafill != null) {
                if (sg2d.clipState == SunGraphics2D.CLIP_SHAPE) {
                    sg2d.textpipe = clipColorText;
                } else {
                    sg2d.textpipe = colorText;
                }
            } else {
                if (sg2d.clipState == SunGraphics2D.CLIP_SHAPE) {
                    sg2d.textpipe = clipPaintText;
                } else {
                    sg2d.textpipe = paintText;
                }
            }
        } else {
            PixelToShapeConverter converter;
            if (canRenderParallelograms(sg2d)) {
                converter = colorViaPgram;
                // Note that we use the transforming pipe here because it
                // will examine the shape and possibly perform an optimized
                // operation if it can be simplified.  The simplifications
                // will be valid for all STROKE and TRANSFORM types.
                sg2d.shapepipe = colorViaPgram;
            } else {
                converter = colorViaShape;
                sg2d.shapepipe = colorPrimitives;
            }
            if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
                sg2d.drawpipe = converter;
                sg2d.fillpipe = converter;
            } else {
                if (sg2d.strokeState != SunGraphics2D.STROKE_THIN) {
                    sg2d.drawpipe = converter;
                } else {
                    sg2d.drawpipe = colorPrimitives;
                }
                sg2d.fillpipe = colorPrimitives;
            }

            sg2d.textpipe = getTextPipe(sg2d, false /* AA==OFF */);
            // assert(sg2d.surfaceData == this);
        }

        // check for loops
        if (sg2d.textpipe  instanceof LoopBasedPipe ||
            sg2d.shapepipe instanceof LoopBasedPipe ||
            sg2d.fillpipe  instanceof LoopBasedPipe ||
            sg2d.drawpipe  instanceof LoopBasedPipe ||
            sg2d.imagepipe instanceof LoopBasedPipe)
        {
            sg2d.loops = getRenderLoops(sg2d);
        }
    }

    /* Return the text pipe to be used based on the graphics AA hint setting,
     * and the rest of the graphics state is compatible with these loops.
     * If the text AA hint is "DEFAULT", then the AA graphics hint requests
     * the AA text renderer, else it requests the B&W text renderer.
     */
    private TextPipe getTextPipe(SunGraphics2D sg2d, boolean aaHintIsOn) {

        /* Try to avoid calling getFontInfo() unless its needed to
         * resolve one of the new AA types.
         */
        switch (sg2d.textAntialiasHint) {
        case SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT:
            if (aaHintIsOn) {
                return aaTextRenderer;
            } else {
                return solidTextRenderer;
            }
        case SunHints.INTVAL_TEXT_ANTIALIAS_OFF:
            return solidTextRenderer;

        case SunHints.INTVAL_TEXT_ANTIALIAS_ON:
            return aaTextRenderer;

        default:
            switch (sg2d.getFontInfo().aaHint) {

            case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_HRGB:
            case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_VRGB:
                return lcdTextRenderer;

            case SunHints.INTVAL_TEXT_ANTIALIAS_ON:
                return aaTextRenderer;

            case SunHints.INTVAL_TEXT_ANTIALIAS_OFF:
                return solidTextRenderer;

                 /* This should not be reached as the FontInfo will
                 * always explicitly set its hint value. So whilst
                 * this could be collapsed to returning say just
                 * solidTextRenderer, or even removed, its left
                 * here in case DEFAULT is ever passed in.
                 */
            default:
                if (aaHintIsOn) {
                    return aaTextRenderer;
                } else {
                    return solidTextRenderer;
                }
            }
        }
    }

    private static SurfaceType getPaintSurfaceType(SunGraphics2D sg2d) {
        switch (sg2d.paintState) {
        case SunGraphics2D.PAINT_OPAQUECOLOR:
            return SurfaceType.OpaqueColor;
        case SunGraphics2D.PAINT_ALPHACOLOR:
            return SurfaceType.AnyColor;
        case SunGraphics2D.PAINT_GRADIENT:
            if (sg2d.paint.getTransparency() == OPAQUE) {
                return SurfaceType.OpaqueGradientPaint;
            } else {
                return SurfaceType.GradientPaint;
            }
        case SunGraphics2D.PAINT_LIN_GRADIENT:
            if (sg2d.paint.getTransparency() == OPAQUE) {
                return SurfaceType.OpaqueLinearGradientPaint;
            } else {
                return SurfaceType.LinearGradientPaint;
            }
        case SunGraphics2D.PAINT_RAD_GRADIENT:
            if (sg2d.paint.getTransparency() == OPAQUE) {
                return SurfaceType.OpaqueRadialGradientPaint;
            } else {
                return SurfaceType.RadialGradientPaint;
            }
        case SunGraphics2D.PAINT_TEXTURE:
            if (sg2d.paint.getTransparency() == OPAQUE) {
                return SurfaceType.OpaqueTexturePaint;
            } else {
                return SurfaceType.TexturePaint;
            }
        default:
        case SunGraphics2D.PAINT_CUSTOM:
            return SurfaceType.AnyPaint;
        }
    }

    private static CompositeType getFillCompositeType(SunGraphics2D sg2d) {
        CompositeType compType = sg2d.imageComp;
        if (sg2d.compositeState == SunGraphics2D.COMP_ISCOPY) {
            if (compType == CompositeType.SrcOverNoEa) {
                compType = CompositeType.OpaqueSrcOverNoEa;
            } else {
                compType = CompositeType.SrcNoEa;
            }
        }
        return compType;
    }

    /**
     * Returns a MaskFill object that can be used on this destination
     * with the source (paint) and composite types determined by the given
     * SunGraphics2D, or null if no such MaskFill object can be located.
     * Subclasses can override this method if they wish to filter other
     * attributes (such as the hardware capabilities of the destination
     * surface) before returning a specific MaskFill object.
     */
    protected MaskFill getMaskFill(SunGraphics2D sg2d) {
        SurfaceType src = getPaintSurfaceType(sg2d);
        CompositeType comp = getFillCompositeType(sg2d);
        SurfaceType dst = getSurfaceType();
        return MaskFill.getFromCache(src, comp, dst);
    }

    private static RenderCache loopcache = new RenderCache(30);

    /**
     * Return a RenderLoops object containing all of the basic
     * GraphicsPrimitive objects for rendering to the destination
     * surface with the current attributes of the given SunGraphics2D.
     */
    public RenderLoops getRenderLoops(SunGraphics2D sg2d) {
        SurfaceType src = getPaintSurfaceType(sg2d);
        CompositeType comp = getFillCompositeType(sg2d);
        SurfaceType dst = sg2d.getSurfaceData().getSurfaceType();

        Object o = loopcache.get(src, comp, dst);
        if (o != null) {
            return (RenderLoops) o;
        }

        RenderLoops loops = makeRenderLoops(src, comp, dst);
        loopcache.put(src, comp, dst, loops);
        return loops;
    }

    /**
     * Construct and return a RenderLoops object containing all of
     * the basic GraphicsPrimitive objects for rendering to the
     * destination surface with the given source, destination, and
     * composite types.
     */
    public static RenderLoops makeRenderLoops(SurfaceType src,
                                              CompositeType comp,
                                              SurfaceType dst)
    {
        RenderLoops loops = new RenderLoops();
        loops.drawLineLoop = DrawLine.locate(src, comp, dst);
        loops.fillRectLoop = FillRect.locate(src, comp, dst);
        loops.drawRectLoop = DrawRect.locate(src, comp, dst);
        loops.drawPolygonsLoop = DrawPolygons.locate(src, comp, dst);
        loops.drawPathLoop = DrawPath.locate(src, comp, dst);
        loops.fillPathLoop = FillPath.locate(src, comp, dst);
        loops.fillSpansLoop = FillSpans.locate(src, comp, dst);
        loops.fillParallelogramLoop = FillParallelogram.locate(src, comp, dst);
        loops.drawParallelogramLoop = DrawParallelogram.locate(src, comp, dst);
        loops.drawGlyphListLoop = DrawGlyphList.locate(src, comp, dst);
        loops.drawGlyphListAALoop = DrawGlyphListAA.locate(src, comp, dst);
        loops.drawGlyphListLCDLoop = DrawGlyphListLCD.locate(src, comp, dst);
        loops.drawGlyphListColorLoop =
                DrawGlyphListColor.locate(src, comp, dst);
        /*
        System.out.println("drawLine: "+loops.drawLineLoop);
        System.out.println("fillRect: "+loops.fillRectLoop);
        System.out.println("drawRect: "+loops.drawRectLoop);
        System.out.println("drawPolygons: "+loops.drawPolygonsLoop);
        System.out.println("fillSpans: "+loops.fillSpansLoop);
        System.out.println("drawGlyphList: "+loops.drawGlyphListLoop);
        System.out.println("drawGlyphListAA: "+loops.drawGlyphListAALoop);
        System.out.println("drawGlyphListLCD: "+loops.drawGlyphListLCDLoop);
        */
        return loops;
    }

    /**
     * Return the GraphicsConfiguration object that describes this
     * destination surface.
     */
    public abstract GraphicsConfiguration getDeviceConfiguration();

    /**
     * Return the SurfaceType object that describes the destination
     * surface.
     */
    public final SurfaceType getSurfaceType() {
        return surfaceType;
    }

    /**
     * Return the ColorModel for the destination surface.
     */
    public final ColorModel getColorModel() {
        return colorModel;
    }

    /**
     * Returns the type of this {@code Transparency}.
     * @return the field type of this {@code Transparency}, which is
     *          either OPAQUE, BITMASK or TRANSLUCENT.
     */
    public int getTransparency() {
        return getColorModel().getTransparency();
    }

    /**
     * Return a readable Raster which contains the pixels for the
     * specified rectangular region of the destination surface.
     * The coordinate origin of the returned Raster is the same as
     * the device space origin of the destination surface.
     * In some cases the returned Raster might also be writeable.
     * In most cases, the returned Raster might contain more pixels
     * than requested.
     *
     * @see #useTightBBoxes
     */
    public abstract Raster getRaster(int x, int y, int w, int h);

    /**
     * Does the pixel accessibility of the destination surface
     * suggest that rendering algorithms might want to take
     * extra time to calculate a more accurate bounding box for
     * the operation being performed?
     * The typical case when this will be true is when a copy of
     * the pixels has to be made when doing a getRaster.  The
     * fewer pixels copied, the faster the operation will go.
     *
     * @see #getRaster
     */
    public boolean useTightBBoxes() {
        // Note: The native equivalent would trigger on VISIBLE_TO_NATIVE
        // REMIND: This is not used - should be obsoleted maybe
        return true;
    }

    /**
     * Returns the pixel data for the specified Argb value packed
     * into an integer for easy storage and conveyance.
     */
    public int pixelFor(int rgb) {
        return surfaceType.pixelFor(rgb, colorModel);
    }

    /**
     * Returns the pixel data for the specified color packed into an
     * integer for easy storage and conveyance.
     *
     * This method will use the getRGB() method of the Color object
     * and defer to the pixelFor(int rgb) method if not overridden.
     *
     * For now this is a convenience function, but for cases where
     * the highest quality color conversion is requested, this method
     * should be overridden in those cases so that a more direct
     * conversion of the color to the destination color space
     * can be done using the additional information in the Color
     * object.
     */
    public int pixelFor(Color c) {
        return pixelFor(c.getRGB());
    }

    /**
     * Returns the Argb representation for the specified integer value
     * which is packed in the format of the associated ColorModel.
     */
    public int rgbFor(int pixel) {
        return surfaceType.rgbFor(pixel, colorModel);
    }

    /**
     * Returns the bounds of the destination surface.
     */
    public abstract Rectangle getBounds();

    /**
     * Fetches private field IndexColorModel.allgrayopaque
     * which is true when all palette entries in the color
     * model are gray and opaque.
     */
    protected static native boolean isOpaqueGray(IndexColorModel icm);

    /**
     * For our purposes null and NullSurfaceData are the same as
     * they represent a disposed surface.
     */
    public static boolean isNull(SurfaceData sd) {
        if (sd == null || sd == NullSurfaceData.theInstance) {
            return true;
        }
        return false;
    }

    /**
     * Performs a copyarea within this surface.  Returns
     * false if there is no algorithm to perform the copyarea
     * given the current settings of the SunGraphics2D.
     *
     * @param x the x coordinate of the area in device space
     * @param y the y coordinate of the area in device space
     * @param w the width of the area in device space
     * @param h the height of the area in device space
     */
    public boolean copyArea(SunGraphics2D sg2d,
                            int x, int y, int w, int h, int dx, int dy)
    {
        return false;
    }

    /**
     * Synchronously releases resources associated with this surface.
     */
    public void flush() {}

    /**
     * Returns destination associated with this SurfaceData.  This could be
     * either an Image or a Component; subclasses of SurfaceData are
     * responsible for returning the appropriate object.
     */
    public abstract Object getDestination();

    /**
     * Returns default horizontal scale factor of the destination surface. Scale
     * factor describes the mapping between virtual and physical coordinates of the
     * SurfaceData. If the scale is 2 then virtual pixel coordinates need to be
     * doubled for physical pixels.
     */
    public double getDefaultScaleX() {
        return 1;
    }

    /**
     * Returns default vertical scale factor of the destination surface. Scale
     * factor describes the mapping between virtual and physical coordinates of the
     * SurfaceData. If the scale is 2 then virtual pixel coordinates need to be
     * doubled for physical pixels.
     */
    public double getDefaultScaleY() {
        return 1;
    }

    /**
     * Converts surfaceData to the particular subclass or throws InvalidPipeException
     */
    public static <T> T convertTo(Class<T> surfaceDataClass, SurfaceData surfaceData) {
        try {
            return surfaceDataClass.cast(surfaceData);
        } catch(ClassCastException e) {
            throw new InvalidPipeException("wrong surface data type: " + surfaceData);
        }
    }
}
