/*
 * Copyright (c) 1999, 2013, 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.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.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 Object blitProxyKey;
    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 key" which will be used
     * along with the SurfaceManager.getCacheData() mechanism to
     * store acceleration-compatible cached copies of source images.
     * This key is a "tag" used to identify which cached copies
     * are compatible with this destination SurfaceData.
     * The getSourceSurfaceData() method uses this key to manage
     * cached copies of a source image as described below.
     * <p>
     * The Object used as this key should be as unique as it needs
     * to be to ensure that multiple acceleratible destinations can
     * each store their cached copies separately under different keys
     * without interfering with each other or getting back the wrong
     * cached copy.
     * <p>
     * Many acceleratable SurfaceData objects can use their own
     * GraphicsConfiguration as their proxy key as the GC object will
     * typically be 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 key Object.
     */
    protected void setBlitProxyKey(Object key) {
        // Caching is effectively disabled if we never have a proxy key
        // since the getSourceSurfaceData() method only does caching
        // if the key is not null.
        if (SurfaceDataProxy.isCachingAllowed()) {
            this.blitProxyKey = key;
        }
    }

    /**
     * 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 blitProxyKey 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 key" (if set) to look for
     *      some cached data stored in 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 &&
            blitProxyKey != null)
        {
            SurfaceDataProxy sdp =
                (SurfaceDataProxy) srcMgr.getCacheData(blitProxyKey);
            if (sdp == null || !sdp.isValid()) {
                if (srcData.getState() == State.UNTRACKABLE) {
                    sdp = SurfaceDataProxy.UNCACHED;
                } else {
                    sdp = makeProxyFor(srcData);
                }
                srcMgr.setCacheData(blitProxyKey, 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();
        solidTextRenderer = new SolidTextRenderer();
        aaTextRenderer = new AATextRenderer();
        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);
        /*
        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</code>.
     * @return the field type of this <code>Transparency</code>, 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();

    static java.security.Permission compPermission;

    /**
     * Performs Security Permissions checks to see if a Custom
     * Composite object should be allowed access to the pixels
     * of this surface.
     */
    protected void checkCustomComposite() {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            if (compPermission == null) {
                compPermission =
                    new java.awt.AWTPermission("readDisplayPixels");
            }
            sm.checkPermission(compPermission);
        }
    }

    /**
     * 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.
     */
    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 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 int getDefaultScale() {
        return 1;
    }
}
