1060 lines · 42.6 KB · Java
RawDownload
/* * Copyright (c) 1999, 2010, 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;

Lines 1–500 of 1060.