/* * Copyright (c) 1999, 2002, 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; /** * 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 { /* * 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. */ public static final String DESC_ANY = "Any CompositeContext"; /** * constant used to describe the Graphics.setXORMode() algorithm */ public static final String DESC_XOR = "XOR mode"; /** * 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. */ 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. */ 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. */ 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); /* * 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. */ public CompositeType deriveSubType(String desc) { return new CompositeType(this, desc); } /** * 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 static int unusedUID = 1; private int uniqueID; private String desc; private CompositeType next; private CompositeType(CompositeType parent, String desc) { next = parent; this.desc = desc; this.uniqueID = makeUniqueID(); } private synchronized static final int makeUniqueID() { if (unusedUID > 255) { throw new InternalError("composite type id overflow"); } return unusedUID++; } 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; } }