/*
 * 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.loops;

import java.awt.image.BufferedImage;
import java.awt.AlphaComposite;
import java.util.HashMap;

A CompositeType object provides a chained description of a type of algorithm for color compositing. The object will provide a single String constant descriptor which is one way of describing a particular compositing algorithm as well as a pointer to another CompositeType which describes a more general algorithm for achieving the same result.

A description of a more specific algorithm is considered a "subtype" and a description of a more general algorithm is considered a "supertype". Thus, the deriveSubType method provides a way to create a new CompositeType that is related to but more specific than an existing CompositeType and the getSuperType method provides a way to ask a given CompositeType for a more general algorithm to achieve the same result.

Note that you cannot construct a brand new root for a chain since the constructor is private. Every chain of types must at some point derive from the Any node provided here using the deriveSubType() method. The presence of this common Any node on every chain ensures that all chains end with the DESC_ANY descriptor so that a suitable General GraphicsPrimitive object can be obtained for the indicated algorithm if all of the more specific searches fail.

/** * A CompositeType object provides a chained description of a type of * algorithm for color compositing. The object will provide a single * String constant descriptor which is one way of describing a particular * compositing algorithm as well as a pointer to another CompositeType * which describes a more general algorithm for achieving the same result. * <p> * A description of a more specific algorithm is considered a "subtype" * and a description of a more general algorithm is considered a "supertype". * Thus, the deriveSubType method provides a way to create a new CompositeType * that is related to but more specific than an existing CompositeType and * the getSuperType method provides a way to ask a given CompositeType * for a more general algorithm to achieve the same result. * <p> * Note that you cannot construct a brand new root for a chain since * the constructor is private. Every chain of types must at some point * derive from the Any node provided here using the deriveSubType() * method. The presence of this common Any node on every chain * ensures that all chains end with the DESC_ANY descriptor so that * a suitable General GraphicsPrimitive object can be obtained for * the indicated algorithm if all of the more specific searches fail. */
public final class CompositeType { private static int unusedUID = 1; private static final HashMap<String,Integer> compositeUIDMap = new HashMap<String,Integer>(100); /* * CONSTANTS USED BY ALL PRIMITIVES TO DESCRIBE THE COMPOSITING * ALGORITHMS THEY CAN PERFORM */
algorithm is a general algorithm that uses a CompositeContext to do the rendering.
/** * algorithm is a general algorithm that uses a CompositeContext * to do the rendering. */
public static final String DESC_ANY = "Any CompositeContext";
constant used to describe the Graphics.setXORMode() algorithm
/** * constant used to describe the Graphics.setXORMode() algorithm */
public static final String DESC_XOR = "XOR mode";
constants used to describe the various AlphaComposite algorithms.
/** * constants used to describe the various AlphaComposite * algorithms. */
public static final String DESC_CLEAR = "Porter-Duff Clear"; public static final String DESC_SRC = "Porter-Duff Src"; public static final String DESC_DST = "Porter-Duff Dst"; public static final String DESC_SRC_OVER = "Porter-Duff Src Over Dst"; public static final String DESC_DST_OVER = "Porter-Duff Dst Over Src"; public static final String DESC_SRC_IN = "Porter-Duff Src In Dst"; public static final String DESC_DST_IN = "Porter-Duff Dst In Src"; public static final String DESC_SRC_OUT = "Porter-Duff Src HeldOutBy Dst"; public static final String DESC_DST_OUT = "Porter-Duff Dst HeldOutBy Src"; public static final String DESC_SRC_ATOP = "Porter-Duff Src Atop Dst"; public static final String DESC_DST_ATOP = "Porter-Duff Dst Atop Src"; public static final String DESC_ALPHA_XOR = "Porter-Duff Xor";
constants used to describe the two common cases of AlphaComposite algorithms that are simpler if there is not extraAlpha.
/** * constants used to describe the two common cases of * AlphaComposite algorithms that are simpler if there * is not extraAlpha. */
public static final String DESC_SRC_NO_EA = "Porter-Duff Src, No Extra Alpha"; public static final String DESC_SRC_OVER_NO_EA = "Porter-Duff SrcOverDst, No Extra Alpha";
constant used to describe an algorithm that implements all 8 of the Porter-Duff rules in one Primitive.
/** * constant used to describe an algorithm that implements all 8 of * the Porter-Duff rules in one Primitive. */
public static final String DESC_ANY_ALPHA = "Any AlphaComposite Rule"; /* * END OF COMPOSITE ALGORITHM TYPE CONSTANTS */
The root CompositeType object for all chains of algorithm descriptions.
/** * The root CompositeType object for all chains of algorithm descriptions. */
public static final CompositeType Any = new CompositeType(null, DESC_ANY); /* * START OF CompositeeType OBJECTS FOR THE VARIOUS CONSTANTS */ public static final CompositeType General = Any; public static final CompositeType AnyAlpha = General.deriveSubType(DESC_ANY_ALPHA); public static final CompositeType Xor = General.deriveSubType(DESC_XOR); public static final CompositeType Clear = AnyAlpha.deriveSubType(DESC_CLEAR); public static final CompositeType Src = AnyAlpha.deriveSubType(DESC_SRC); public static final CompositeType Dst = AnyAlpha.deriveSubType(DESC_DST); public static final CompositeType SrcOver = AnyAlpha.deriveSubType(DESC_SRC_OVER); public static final CompositeType DstOver = AnyAlpha.deriveSubType(DESC_DST_OVER); public static final CompositeType SrcIn = AnyAlpha.deriveSubType(DESC_SRC_IN); public static final CompositeType DstIn = AnyAlpha.deriveSubType(DESC_DST_IN); public static final CompositeType SrcOut = AnyAlpha.deriveSubType(DESC_SRC_OUT); public static final CompositeType DstOut = AnyAlpha.deriveSubType(DESC_DST_OUT); public static final CompositeType SrcAtop = AnyAlpha.deriveSubType(DESC_SRC_ATOP); public static final CompositeType DstAtop = AnyAlpha.deriveSubType(DESC_DST_ATOP); public static final CompositeType AlphaXor = AnyAlpha.deriveSubType(DESC_ALPHA_XOR); public static final CompositeType SrcNoEa = Src.deriveSubType(DESC_SRC_NO_EA); public static final CompositeType SrcOverNoEa = SrcOver.deriveSubType(DESC_SRC_OVER_NO_EA); /* * A special CompositeType for the case where we are filling in * SrcOverNoEa mode with an opaque color. In that case then the * best loop for us to use would be a SrcNoEa loop, but what if * there is no such loop? In that case then we would end up * backing off to a Src loop (which should still be fine) or an * AnyAlpha loop which would be slower than a SrcOver loop in * most cases. * The fix is to use the following chain which looks for loops * in the following order: * SrcNoEa, Src, SrcOverNoEa, SrcOver, AnyAlpha */ public static final CompositeType OpaqueSrcOverNoEa = SrcOverNoEa.deriveSubType(DESC_SRC) .deriveSubType(DESC_SRC_NO_EA); /* * END OF CompositeType OBJECTS FOR THE VARIOUS CONSTANTS */
Return a new CompositeType object which uses this object as its more general "supertype" descriptor. If no operation can be found that implements the algorithm described more exactly by desc, then this object will define the more general compositing algorithm that can be used instead.
/** * Return a new CompositeType object which uses this object as its * more general "supertype" descriptor. If no operation can be * found that implements the algorithm described more exactly * by desc, then this object will define the more general * compositing algorithm that can be used instead. */
public CompositeType deriveSubType(String desc) { return new CompositeType(this, desc); }
Return a CompositeType object for the specified AlphaComposite rule.
/** * Return a CompositeType object for the specified AlphaComposite * rule. */
public static CompositeType forAlphaComposite(AlphaComposite ac) { switch (ac.getRule()) { case AlphaComposite.CLEAR: return Clear; case AlphaComposite.SRC: if (ac.getAlpha() >= 1.0f) { return SrcNoEa; } else { return Src; } case AlphaComposite.DST: return Dst; case AlphaComposite.SRC_OVER: if (ac.getAlpha() >= 1.0f) { return SrcOverNoEa; } else { return SrcOver; } case AlphaComposite.DST_OVER: return DstOver; case AlphaComposite.SRC_IN: return SrcIn; case AlphaComposite.DST_IN: return DstIn; case AlphaComposite.SRC_OUT: return SrcOut; case AlphaComposite.DST_OUT: return DstOut; case AlphaComposite.SRC_ATOP: return SrcAtop; case AlphaComposite.DST_ATOP: return DstAtop; case AlphaComposite.XOR: return AlphaXor; default: throw new InternalError("Unrecognized alpha rule"); } } private int uniqueID; private String desc; private CompositeType next; private CompositeType(CompositeType parent, String desc) { next = parent; this.desc = desc; this.uniqueID = makeUniqueID(desc); } public synchronized static final int makeUniqueID(String desc) { Integer i = compositeUIDMap.get(desc); if (i == null) { if (unusedUID > 255) { throw new InternalError("composite type id overflow"); } i = unusedUID++; compositeUIDMap.put(desc, i); } return i; } public int getUniqueID() { return uniqueID; } public String getDescriptor() { return desc; } public CompositeType getSuperType() { return next; } public int hashCode() { return desc.hashCode(); } public boolean isDerivedFrom(CompositeType other) { CompositeType comptype = this; do { if (comptype.desc == other.desc) { return true; } comptype = comptype.next; } while (comptype != null); return false; } public boolean equals(Object o) { if (o instanceof CompositeType) { return (((CompositeType) o).uniqueID == this.uniqueID); } return false; } public String toString() { return desc; } }