0N/A/*
3261N/A * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage java.awt;
0N/A
0N/Aimport java.awt.image.ColorModel;
0N/Aimport sun.java2d.SunCompositeContext;
0N/A
0N/A/**
0N/A * The <code>AlphaComposite</code> class implements basic alpha
0N/A * compositing rules for combining source and destination colors
0N/A * to achieve blending and transparency effects with graphics and
0N/A * images.
0N/A * The specific rules implemented by this class are the basic set
0N/A * of 12 rules described in
0N/A * T. Porter and T. Duff, "Compositing Digital Images", SIGGRAPH 84,
0N/A * 253-259.
0N/A * The rest of this documentation assumes some familiarity with the
0N/A * definitions and concepts outlined in that paper.
0N/A *
0N/A * <p>
0N/A * This class extends the standard equations defined by Porter and
0N/A * Duff to include one additional factor.
0N/A * An instance of the <code>AlphaComposite</code> class can contain
0N/A * an alpha value that is used to modify the opacity or coverage of
0N/A * every source pixel before it is used in the blending equations.
0N/A *
0N/A * <p>
0N/A * It is important to note that the equations defined by the Porter
0N/A * and Duff paper are all defined to operate on color components
0N/A * that are premultiplied by their corresponding alpha components.
0N/A * Since the <code>ColorModel</code> and <code>Raster</code> classes
0N/A * allow the storage of pixel data in either premultiplied or
0N/A * non-premultiplied form, all input data must be normalized into
0N/A * premultiplied form before applying the equations and all results
0N/A * might need to be adjusted back to the form required by the destination
0N/A * before the pixel values are stored.
0N/A *
0N/A * <p>
0N/A * Also note that this class defines only the equations
0N/A * for combining color and alpha values in a purely mathematical
0N/A * sense. The accurate application of its equations depends
0N/A * on the way the data is retrieved from its sources and stored
0N/A * in its destinations.
0N/A * See <a href="#caveats">Implementation Caveats</a>
0N/A * for further information.
0N/A *
0N/A * <p>
0N/A * The following factors are used in the description of the blending
0N/A * equation in the Porter and Duff paper:
0N/A *
0N/A * <blockquote>
0N/A * <table summary="layout">
0N/A * <tr><th align=left>Factor&nbsp;&nbsp;<th align=left>Definition
0N/A * <tr><td><em>A<sub>s</sub></em><td>the alpha component of the source pixel
0N/A * <tr><td><em>C<sub>s</sub></em><td>a color component of the source pixel in premultiplied form
0N/A * <tr><td><em>A<sub>d</sub></em><td>the alpha component of the destination pixel
0N/A * <tr><td><em>C<sub>d</sub></em><td>a color component of the destination pixel in premultiplied form
0N/A * <tr><td><em>F<sub>s</sub></em><td>the fraction of the source pixel that contributes to the output
0N/A * <tr><td><em>F<sub>d</sub></em><td>the fraction of the destination pixel that contributes
0N/A * to the output
0N/A * <tr><td><em>A<sub>r</sub></em><td>the alpha component of the result
0N/A * <tr><td><em>C<sub>r</sub></em><td>a color component of the result in premultiplied form
0N/A * </table>
0N/A * </blockquote>
0N/A *
0N/A * <p>
0N/A * Using these factors, Porter and Duff define 12 ways of choosing
0N/A * the blending factors <em>F<sub>s</sub></em> and <em>F<sub>d</sub></em> to
0N/A * produce each of 12 desirable visual effects.
0N/A * The equations for determining <em>F<sub>s</sub></em> and <em>F<sub>d</sub></em>
0N/A * are given in the descriptions of the 12 static fields
0N/A * that specify visual effects.
0N/A * For example,
0N/A * the description for
0N/A * <a href="#SRC_OVER"><code>SRC_OVER</code></a>
0N/A * specifies that <em>F<sub>s</sub></em> = 1 and <em>F<sub>d</sub></em> = (1-<em>A<sub>s</sub></em>).
0N/A * Once a set of equations for determining the blending factors is
0N/A * known they can then be applied to each pixel to produce a result
0N/A * using the following set of equations:
0N/A *
0N/A * <pre>
0N/A * <em>F<sub>s</sub></em> = <em>f</em>(<em>A<sub>d</sub></em>)
0N/A * <em>F<sub>d</sub></em> = <em>f</em>(<em>A<sub>s</sub></em>)
0N/A * <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>*<em>F<sub>s</sub></em> + <em>A<sub>d</sub></em>*<em>F<sub>d</sub></em>
0N/A * <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>*<em>F<sub>s</sub></em> + <em>C<sub>d</sub></em>*<em>F<sub>d</sub></em></pre>
0N/A *
0N/A * <p>
0N/A * The following factors will be used to discuss our extensions to
0N/A * the blending equation in the Porter and Duff paper:
0N/A *
0N/A * <blockquote>
0N/A * <table summary="layout">
0N/A * <tr><th align=left>Factor&nbsp;&nbsp;<th align=left>Definition
0N/A * <tr><td><em>C<sub>sr</sub></em> <td>one of the raw color components of the source pixel
0N/A * <tr><td><em>C<sub>dr</sub></em> <td>one of the raw color components of the destination pixel
0N/A * <tr><td><em>A<sub>ac</sub></em> <td>the "extra" alpha component from the AlphaComposite instance
0N/A * <tr><td><em>A<sub>sr</sub></em> <td>the raw alpha component of the source pixel
0N/A * <tr><td><em>A<sub>dr</sub></em><td>the raw alpha component of the destination pixel
0N/A * <tr><td><em>A<sub>df</sub></em> <td>the final alpha component stored in the destination
0N/A * <tr><td><em>C<sub>df</sub></em> <td>the final raw color component stored in the destination
0N/A * </table>
0N/A *</blockquote>
0N/A *
0N/A * <h3>Preparing Inputs</h3>
0N/A *
0N/A * <p>
0N/A * The <code>AlphaComposite</code> class defines an additional alpha
0N/A * value that is applied to the source alpha.
0N/A * This value is applied as if an implicit SRC_IN rule were first
0N/A * applied to the source pixel against a pixel with the indicated
0N/A * alpha by multiplying both the raw source alpha and the raw
0N/A * source colors by the alpha in the <code>AlphaComposite</code>.
0N/A * This leads to the following equation for producing the alpha
0N/A * used in the Porter and Duff blending equation:
0N/A *
0N/A * <pre>
0N/A * <em>A<sub>s</sub></em> = <em>A<sub>sr</sub></em> * <em>A<sub>ac</sub></em> </pre>
0N/A *
0N/A * All of the raw source color components need to be multiplied
0N/A * by the alpha in the <code>AlphaComposite</code> instance.
0N/A * Additionally, if the source was not in premultiplied form
0N/A * then the color components also need to be multiplied by the
0N/A * source alpha.
0N/A * Thus, the equation for producing the source color components
0N/A * for the Porter and Duff equation depends on whether the source
0N/A * pixels are premultiplied or not:
0N/A *
0N/A * <pre>
0N/A * <em>C<sub>s</sub></em> = <em>C<sub>sr</sub></em> * <em>A<sub>sr</sub></em> * <em>A<sub>ac</sub></em> (if source is not premultiplied)
0N/A * <em>C<sub>s</sub></em> = <em>C<sub>sr</sub></em> * <em>A<sub>ac</sub></em> (if source is premultiplied) </pre>
0N/A *
0N/A * No adjustment needs to be made to the destination alpha:
0N/A *
0N/A * <pre>
0N/A * <em>A<sub>d</sub></em> = <em>A<sub>dr</sub></em> </pre>
0N/A *
0N/A * <p>
0N/A * The destination color components need to be adjusted only if
0N/A * they are not in premultiplied form:
0N/A *
0N/A * <pre>
0N/A * <em>C<sub>d</sub></em> = <em>C<sub>dr</sub></em> * <em>A<sub>d</sub></em> (if destination is not premultiplied)
0N/A * <em>C<sub>d</sub></em> = <em>C<sub>dr</sub></em> (if destination is premultiplied) </pre>
0N/A *
0N/A * <h3>Applying the Blending Equation</h3>
0N/A *
0N/A * <p>
0N/A * The adjusted <em>A<sub>s</sub></em>, <em>A<sub>d</sub></em>,
0N/A * <em>C<sub>s</sub></em>, and <em>C<sub>d</sub></em> are used in the standard
0N/A * Porter and Duff equations to calculate the blending factors
0N/A * <em>F<sub>s</sub></em> and <em>F<sub>d</sub></em> and then the resulting
0N/A * premultiplied components <em>A<sub>r</sub></em> and <em>C<sub>r</sub></em>.
0N/A *
0N/A * <p>
0N/A * <h3>Preparing Results</h3>
0N/A *
0N/A * <p>
0N/A * The results only need to be adjusted if they are to be stored
0N/A * back into a destination buffer that holds data that is not
0N/A * premultiplied, using the following equations:
0N/A *
0N/A * <pre>
0N/A * <em>A<sub>df</sub></em> = <em>A<sub>r</sub></em>
0N/A * <em>C<sub>df</sub></em> = <em>C<sub>r</sub></em> (if dest is premultiplied)
0N/A * <em>C<sub>df</sub></em> = <em>C<sub>r</sub></em> / <em>A<sub>r</sub></em> (if dest is not premultiplied) </pre>
0N/A *
0N/A * Note that since the division is undefined if the resulting alpha
0N/A * is zero, the division in that case is omitted to avoid the "divide
0N/A * by zero" and the color components are left as
0N/A * all zeros.
0N/A *
0N/A * <p>
0N/A * <h3>Performance Considerations</h3>
0N/A *
0N/A * <p>
0N/A * For performance reasons, it is preferrable that
0N/A * <code>Raster</code> objects passed to the <code>compose</code>
0N/A * method of a {@link CompositeContext} object created by the
0N/A * <code>AlphaComposite</code> class have premultiplied data.
0N/A * If either the source <code>Raster</code>
0N/A * or the destination <code>Raster</code>
0N/A * is not premultiplied, however,
0N/A * appropriate conversions are performed before and after the compositing
0N/A * operation.
0N/A *
0N/A * <h3><a name="caveats">Implementation Caveats</a></h3>
0N/A *
0N/A * <ul>
0N/A * <li>
0N/A * Many sources, such as some of the opaque image types listed
0N/A * in the <code>BufferedImage</code> class, do not store alpha values
0N/A * for their pixels. Such sources supply an alpha of 1.0 for
0N/A * all of their pixels.
0N/A *
0N/A * <p>
0N/A * <li>
0N/A * Many destinations also have no place to store the alpha values
0N/A * that result from the blending calculations performed by this class.
0N/A * Such destinations thus implicitly discard the resulting
0N/A * alpha values that this class produces.
0N/A * It is recommended that such destinations should treat their stored
0N/A * color values as non-premultiplied and divide the resulting color
0N/A * values by the resulting alpha value before storing the color
0N/A * values and discarding the alpha value.
0N/A *
0N/A * <p>
0N/A * <li>
0N/A * The accuracy of the results depends on the manner in which pixels
0N/A * are stored in the destination.
0N/A * An image format that provides at least 8 bits of storage per color
0N/A * and alpha component is at least adequate for use as a destination
0N/A * for a sequence of a few to a dozen compositing operations.
0N/A * An image format with fewer than 8 bits of storage per component
0N/A * is of limited use for just one or two compositing operations
0N/A * before the rounding errors dominate the results.
0N/A * An image format
0N/A * that does not separately store
0N/A * color components is not a
0N/A * good candidate for any type of translucent blending.
0N/A * For example, <code>BufferedImage.TYPE_BYTE_INDEXED</code>
0N/A * should not be used as a destination for a blending operation
0N/A * because every operation
0N/A * can introduce large errors, due to
0N/A * the need to choose a pixel from a limited palette to match the
0N/A * results of the blending equations.
0N/A *
0N/A * <p>
0N/A * <li>
0N/A * Nearly all formats store pixels as discrete integers rather than
0N/A * the floating point values used in the reference equations above.
0N/A * The implementation can either scale the integer pixel
0N/A * values into floating point values in the range 0.0 to 1.0 or
0N/A * use slightly modified versions of the equations
0N/A * that operate entirely in the integer domain and yet produce
0N/A * analogous results to the reference equations.
0N/A *
0N/A * <p>
0N/A * Typically the integer values are related to the floating point
0N/A * values in such a way that the integer 0 is equated
0N/A * to the floating point value 0.0 and the integer
0N/A * 2^<em>n</em>-1 (where <em>n</em> is the number of bits
0N/A * in the representation) is equated to 1.0.
0N/A * For 8-bit representations, this means that 0x00
0N/A * represents 0.0 and 0xff represents
0N/A * 1.0.
0N/A *
0N/A * <p>
0N/A * <li>
0N/A * The internal implementation can approximate some of the equations
0N/A * and it can also eliminate some steps to avoid unnecessary operations.
0N/A * For example, consider a discrete integer image with non-premultiplied
0N/A * alpha values that uses 8 bits per component for storage.
0N/A * The stored values for a
0N/A * nearly transparent darkened red might be:
0N/A *
0N/A * <pre>
0N/A * (A, R, G, B) = (0x01, 0xb0, 0x00, 0x00)</pre>
0N/A *
0N/A * <p>
0N/A * If integer math were being used and this value were being
0N/A * composited in
0N/A * <a href="#SRC"><code>SRC</code></a>
0N/A * mode with no extra alpha, then the math would
0N/A * indicate that the results were (in integer format):
0N/A *
0N/A * <pre>
0N/A * (A, R, G, B) = (0x01, 0x01, 0x00, 0x00)</pre>
0N/A *
0N/A * <p>
0N/A * Note that the intermediate values, which are always in premultiplied
0N/A * form, would only allow the integer red component to be either 0x00
0N/A * or 0x01. When we try to store this result back into a destination
0N/A * that is not premultiplied, dividing out the alpha will give us
0N/A * very few choices for the non-premultiplied red value.
0N/A * In this case an implementation that performs the math in integer
0N/A * space without shortcuts is likely to end up with the final pixel
0N/A * values of:
0N/A *
0N/A * <pre>
0N/A * (A, R, G, B) = (0x01, 0xff, 0x00, 0x00)</pre>
0N/A *
0N/A * <p>
0N/A * (Note that 0x01 divided by 0x01 gives you 1.0, which is equivalent
0N/A * to the value 0xff in an 8-bit storage format.)
0N/A *
0N/A * <p>
0N/A * Alternately, an implementation that uses floating point math
0N/A * might produce more accurate results and end up returning to the
0N/A * original pixel value with little, if any, roundoff error.
0N/A * Or, an implementation using integer math might decide that since
0N/A * the equations boil down to a virtual NOP on the color values
0N/A * if performed in a floating point space, it can transfer the
0N/A * pixel untouched to the destination and avoid all the math entirely.
0N/A *
0N/A * <p>
0N/A * These implementations all attempt to honor the
0N/A * same equations, but use different tradeoffs of integer and
0N/A * floating point math and reduced or full equations.
0N/A * To account for such differences, it is probably best to
0N/A * expect only that the premultiplied form of the results to
0N/A * match between implementations and image formats. In this
0N/A * case both answers, expressed in premultiplied form would
0N/A * equate to:
0N/A *
0N/A * <pre>
0N/A * (A, R, G, B) = (0x01, 0x01, 0x00, 0x00)</pre>
0N/A *
0N/A * <p>
0N/A * and thus they would all match.
0N/A *
0N/A * <p>
0N/A * <li>
0N/A * Because of the technique of simplifying the equations for
0N/A * calculation efficiency, some implementations might perform
0N/A * differently when encountering result alpha values of 0.0
0N/A * on a non-premultiplied destination.
0N/A * Note that the simplification of removing the divide by alpha
0N/A * in the case of the SRC rule is technically not valid if the
0N/A * denominator (alpha) is 0.
0N/A * But, since the results should only be expected to be accurate
0N/A * when viewed in premultiplied form, a resulting alpha of 0
0N/A * essentially renders the resulting color components irrelevant
0N/A * and so exact behavior in this case should not be expected.
0N/A * </ul>
0N/A * @see Composite
0N/A * @see CompositeContext
0N/A */
0N/A
0N/Apublic final class AlphaComposite implements Composite {
0N/A /**
0N/A * Both the color and the alpha of the destination are cleared
0N/A * (Porter-Duff Clear rule).
0N/A * Neither the source nor the destination is used as input.
0N/A *<p>
0N/A * <em>F<sub>s</sub></em> = 0 and <em>F<sub>d</sub></em> = 0, thus:
0N/A *<pre>
0N/A * <em>A<sub>r</sub></em> = 0
0N/A * <em>C<sub>r</sub></em> = 0
0N/A *</pre>
0N/A */
0N/A public static final int CLEAR = 1;
0N/A
0N/A /**
0N/A * The source is copied to the destination
0N/A * (Porter-Duff Source rule).
0N/A * The destination is not used as input.
0N/A *<p>
0N/A * <em>F<sub>s</sub></em> = 1 and <em>F<sub>d</sub></em> = 0, thus:
0N/A *<pre>
0N/A * <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>
0N/A * <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>
0N/A *</pre>
0N/A */
0N/A public static final int SRC = 2;
0N/A
0N/A /**
0N/A * The destination is left untouched
0N/A * (Porter-Duff Destination rule).
0N/A *<p>
0N/A * <em>F<sub>s</sub></em> = 0 and <em>F<sub>d</sub></em> = 1, thus:
0N/A *<pre>
0N/A * <em>A<sub>r</sub></em> = <em>A<sub>d</sub></em>
0N/A * <em>C<sub>r</sub></em> = <em>C<sub>d</sub></em>
0N/A *</pre>
0N/A * @since 1.4
0N/A */
0N/A public static final int DST = 9;
0N/A // Note that DST was added in 1.4 so it is numbered out of order...
0N/A
0N/A /**
0N/A * The source is composited over the destination
0N/A * (Porter-Duff Source Over Destination rule).
0N/A *<p>
0N/A * <em>F<sub>s</sub></em> = 1 and <em>F<sub>d</sub></em> = (1-<em>A<sub>s</sub></em>), thus:
0N/A *<pre>
0N/A * <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em> + <em>A<sub>d</sub></em>*(1-<em>A<sub>s</sub></em>)
0N/A * <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em> + <em>C<sub>d</sub></em>*(1-<em>A<sub>s</sub></em>)
0N/A *</pre>
0N/A */
0N/A public static final int SRC_OVER = 3;
0N/A
0N/A /**
0N/A * The destination is composited over the source and
0N/A * the result replaces the destination
0N/A * (Porter-Duff Destination Over Source rule).
0N/A *<p>
0N/A * <em>F<sub>s</sub></em> = (1-<em>A<sub>d</sub></em>) and <em>F<sub>d</sub></em> = 1, thus:
0N/A *<pre>
0N/A * <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>*(1-<em>A<sub>d</sub></em>) + <em>A<sub>d</sub></em>
0N/A * <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>*(1-<em>A<sub>d</sub></em>) + <em>C<sub>d</sub></em>
0N/A *</pre>
0N/A */
0N/A public static final int DST_OVER = 4;
0N/A
0N/A /**
0N/A * The part of the source lying inside of the destination replaces
0N/A * the destination
0N/A * (Porter-Duff Source In Destination rule).
0N/A *<p>
0N/A * <em>F<sub>s</sub></em> = <em>A<sub>d</sub></em> and <em>F<sub>d</sub></em> = 0, thus:
0N/A *<pre>
0N/A * <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>*<em>A<sub>d</sub></em>
0N/A * <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>*<em>A<sub>d</sub></em>
0N/A *</pre>
0N/A */
0N/A public static final int SRC_IN = 5;
0N/A
0N/A /**
0N/A * The part of the destination lying inside of the source
0N/A * replaces the destination
0N/A * (Porter-Duff Destination In Source rule).
0N/A *<p>
0N/A * <em>F<sub>s</sub></em> = 0 and <em>F<sub>d</sub></em> = <em>A<sub>s</sub></em>, thus:
0N/A *<pre>
0N/A * <em>A<sub>r</sub></em> = <em>A<sub>d</sub></em>*<em>A<sub>s</sub></em>
0N/A * <em>C<sub>r</sub></em> = <em>C<sub>d</sub></em>*<em>A<sub>s</sub></em>
0N/A *</pre>
0N/A */
0N/A public static final int DST_IN = 6;
0N/A
0N/A /**
0N/A * The part of the source lying outside of the destination
0N/A * replaces the destination
0N/A * (Porter-Duff Source Held Out By Destination rule).
0N/A *<p>
0N/A * <em>F<sub>s</sub></em> = (1-<em>A<sub>d</sub></em>) and <em>F<sub>d</sub></em> = 0, thus:
0N/A *<pre>
0N/A * <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>*(1-<em>A<sub>d</sub></em>)
0N/A * <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>*(1-<em>A<sub>d</sub></em>)
0N/A *</pre>
0N/A */
0N/A public static final int SRC_OUT = 7;
0N/A
0N/A /**
0N/A * The part of the destination lying outside of the source
0N/A * replaces the destination
0N/A * (Porter-Duff Destination Held Out By Source rule).
0N/A *<p>
0N/A * <em>F<sub>s</sub></em> = 0 and <em>F<sub>d</sub></em> = (1-<em>A<sub>s</sub></em>), thus:
0N/A *<pre>
0N/A * <em>A<sub>r</sub></em> = <em>A<sub>d</sub></em>*(1-<em>A<sub>s</sub></em>)
0N/A * <em>C<sub>r</sub></em> = <em>C<sub>d</sub></em>*(1-<em>A<sub>s</sub></em>)
0N/A *</pre>
0N/A */
0N/A public static final int DST_OUT = 8;
0N/A
0N/A // Rule 9 is DST which is defined above where it fits into the
0N/A // list logically, rather than numerically
0N/A //
0N/A // public static final int DST = 9;
0N/A
0N/A /**
0N/A * The part of the source lying inside of the destination
0N/A * is composited onto the destination
0N/A * (Porter-Duff Source Atop Destination rule).
0N/A *<p>
0N/A * <em>F<sub>s</sub></em> = <em>A<sub>d</sub></em> and <em>F<sub>d</sub></em> = (1-<em>A<sub>s</sub></em>), thus:
0N/A *<pre>
0N/A * <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>*<em>A<sub>d</sub></em> + <em>A<sub>d</sub></em>*(1-<em>A<sub>s</sub></em>) = <em>A<sub>d</sub></em>
0N/A * <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>*<em>A<sub>d</sub></em> + <em>C<sub>d</sub></em>*(1-<em>A<sub>s</sub></em>)
0N/A *</pre>
0N/A * @since 1.4
0N/A */
0N/A public static final int SRC_ATOP = 10;
0N/A
0N/A /**
0N/A * The part of the destination lying inside of the source
0N/A * is composited over the source and replaces the destination
0N/A * (Porter-Duff Destination Atop Source rule).
0N/A *<p>
0N/A * <em>F<sub>s</sub></em> = (1-<em>A<sub>d</sub></em>) and <em>F<sub>d</sub></em> = <em>A<sub>s</sub></em>, thus:
0N/A *<pre>
0N/A * <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>*(1-<em>A<sub>d</sub></em>) + <em>A<sub>d</sub></em>*<em>A<sub>s</sub></em> = <em>A<sub>s</sub></em>
0N/A * <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>*(1-<em>A<sub>d</sub></em>) + <em>C<sub>d</sub></em>*<em>A<sub>s</sub></em>
0N/A *</pre>
0N/A * @since 1.4
0N/A */
0N/A public static final int DST_ATOP = 11;
0N/A
0N/A /**
0N/A * The part of the source that lies outside of the destination
0N/A * is combined with the part of the destination that lies outside
0N/A * of the source
0N/A * (Porter-Duff Source Xor Destination rule).
0N/A *<p>
0N/A * <em>F<sub>s</sub></em> = (1-<em>A<sub>d</sub></em>) and <em>F<sub>d</sub></em> = (1-<em>A<sub>s</sub></em>), thus:
0N/A *<pre>
0N/A * <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>*(1-<em>A<sub>d</sub></em>) + <em>A<sub>d</sub></em>*(1-<em>A<sub>s</sub></em>)
0N/A * <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>*(1-<em>A<sub>d</sub></em>) + <em>C<sub>d</sub></em>*(1-<em>A<sub>s</sub></em>)
0N/A *</pre>
0N/A * @since 1.4
0N/A */
0N/A public static final int XOR = 12;
0N/A
0N/A /**
0N/A * <code>AlphaComposite</code> object that implements the opaque CLEAR rule
0N/A * with an alpha of 1.0f.
0N/A * @see #CLEAR
0N/A */
0N/A public static final AlphaComposite Clear = new AlphaComposite(CLEAR);
0N/A
0N/A /**
0N/A * <code>AlphaComposite</code> object that implements the opaque SRC rule
0N/A * with an alpha of 1.0f.
0N/A * @see #SRC
0N/A */
0N/A public static final AlphaComposite Src = new AlphaComposite(SRC);
0N/A
0N/A /**
0N/A * <code>AlphaComposite</code> object that implements the opaque DST rule
0N/A * with an alpha of 1.0f.
0N/A * @see #DST
0N/A * @since 1.4
0N/A */
0N/A public static final AlphaComposite Dst = new AlphaComposite(DST);
0N/A
0N/A /**
0N/A * <code>AlphaComposite</code> object that implements the opaque SRC_OVER rule
0N/A * with an alpha of 1.0f.
0N/A * @see #SRC_OVER
0N/A */
0N/A public static final AlphaComposite SrcOver = new AlphaComposite(SRC_OVER);
0N/A
0N/A /**
0N/A * <code>AlphaComposite</code> object that implements the opaque DST_OVER rule
0N/A * with an alpha of 1.0f.
0N/A * @see #DST_OVER
0N/A */
0N/A public static final AlphaComposite DstOver = new AlphaComposite(DST_OVER);
0N/A
0N/A /**
0N/A * <code>AlphaComposite</code> object that implements the opaque SRC_IN rule
0N/A * with an alpha of 1.0f.
0N/A * @see #SRC_IN
0N/A */
0N/A public static final AlphaComposite SrcIn = new AlphaComposite(SRC_IN);
0N/A
0N/A /**
0N/A * <code>AlphaComposite</code> object that implements the opaque DST_IN rule
0N/A * with an alpha of 1.0f.
0N/A * @see #DST_IN
0N/A */
0N/A public static final AlphaComposite DstIn = new AlphaComposite(DST_IN);
0N/A
0N/A /**
0N/A * <code>AlphaComposite</code> object that implements the opaque SRC_OUT rule
0N/A * with an alpha of 1.0f.
0N/A * @see #SRC_OUT
0N/A */
0N/A public static final AlphaComposite SrcOut = new AlphaComposite(SRC_OUT);
0N/A
0N/A /**
0N/A * <code>AlphaComposite</code> object that implements the opaque DST_OUT rule
0N/A * with an alpha of 1.0f.
0N/A * @see #DST_OUT
0N/A */
0N/A public static final AlphaComposite DstOut = new AlphaComposite(DST_OUT);
0N/A
0N/A /**
0N/A * <code>AlphaComposite</code> object that implements the opaque SRC_ATOP rule
0N/A * with an alpha of 1.0f.
0N/A * @see #SRC_ATOP
0N/A * @since 1.4
0N/A */
0N/A public static final AlphaComposite SrcAtop = new AlphaComposite(SRC_ATOP);
0N/A
0N/A /**
0N/A * <code>AlphaComposite</code> object that implements the opaque DST_ATOP rule
0N/A * with an alpha of 1.0f.
0N/A * @see #DST_ATOP
0N/A * @since 1.4
0N/A */
0N/A public static final AlphaComposite DstAtop = new AlphaComposite(DST_ATOP);
0N/A
0N/A /**
0N/A * <code>AlphaComposite</code> object that implements the opaque XOR rule
0N/A * with an alpha of 1.0f.
0N/A * @see #XOR
0N/A * @since 1.4
0N/A */
0N/A public static final AlphaComposite Xor = new AlphaComposite(XOR);
0N/A
0N/A private static final int MIN_RULE = CLEAR;
0N/A private static final int MAX_RULE = XOR;
0N/A
0N/A float extraAlpha;
0N/A int rule;
0N/A
0N/A private AlphaComposite(int rule) {
0N/A this(rule, 1.0f);
0N/A }
0N/A
0N/A private AlphaComposite(int rule, float alpha) {
0N/A if (rule < MIN_RULE || rule > MAX_RULE) {
0N/A throw new IllegalArgumentException("unknown composite rule");
0N/A }
2167N/A if (alpha >= 0.0f && alpha <= 1.0f) {
2167N/A this.rule = rule;
2167N/A this.extraAlpha = alpha;
2167N/A } else {
2167N/A throw new IllegalArgumentException("alpha value out of range");
2167N/A }
0N/A }
0N/A
0N/A /**
0N/A * Creates an <code>AlphaComposite</code> object with the specified rule.
0N/A * @param rule the compositing rule
0N/A * @throws IllegalArgumentException if <code>rule</code> is not one of
0N/A * the following: {@link #CLEAR}, {@link #SRC}, {@link #DST},
0N/A * {@link #SRC_OVER}, {@link #DST_OVER}, {@link #SRC_IN},
0N/A * {@link #DST_IN}, {@link #SRC_OUT}, {@link #DST_OUT},
0N/A * {@link #SRC_ATOP}, {@link #DST_ATOP}, or {@link #XOR}
0N/A */
0N/A public static AlphaComposite getInstance(int rule) {
0N/A switch (rule) {
0N/A case CLEAR:
0N/A return Clear;
0N/A case SRC:
0N/A return Src;
0N/A case DST:
0N/A return Dst;
0N/A case SRC_OVER:
0N/A return SrcOver;
0N/A case DST_OVER:
0N/A return DstOver;
0N/A case SRC_IN:
0N/A return SrcIn;
0N/A case DST_IN:
0N/A return DstIn;
0N/A case SRC_OUT:
0N/A return SrcOut;
0N/A case DST_OUT:
0N/A return DstOut;
0N/A case SRC_ATOP:
0N/A return SrcAtop;
0N/A case DST_ATOP:
0N/A return DstAtop;
0N/A case XOR:
0N/A return Xor;
0N/A default:
0N/A throw new IllegalArgumentException("unknown composite rule");
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Creates an <code>AlphaComposite</code> object with the specified rule and
0N/A * the constant alpha to multiply with the alpha of the source.
0N/A * The source is multiplied with the specified alpha before being composited
0N/A * with the destination.
0N/A * @param rule the compositing rule
0N/A * @param alpha the constant alpha to be multiplied with the alpha of
0N/A * the source. <code>alpha</code> must be a floating point number in the
0N/A * inclusive range [0.0,&nbsp;1.0].
0N/A * @throws IllegalArgumentException if
0N/A * <code>alpha</code> is less than 0.0 or greater than 1.0, or if
0N/A * <code>rule</code> is not one of
0N/A * the following: {@link #CLEAR}, {@link #SRC}, {@link #DST},
0N/A * {@link #SRC_OVER}, {@link #DST_OVER}, {@link #SRC_IN},
0N/A * {@link #DST_IN}, {@link #SRC_OUT}, {@link #DST_OUT},
0N/A * {@link #SRC_ATOP}, {@link #DST_ATOP}, or {@link #XOR}
0N/A */
0N/A public static AlphaComposite getInstance(int rule, float alpha) {
0N/A if (alpha == 1.0f) {
0N/A return getInstance(rule);
0N/A }
0N/A return new AlphaComposite(rule, alpha);
0N/A }
0N/A
0N/A /**
0N/A * Creates a context for the compositing operation.
0N/A * The context contains state that is used in performing
0N/A * the compositing operation.
0N/A * @param srcColorModel the {@link ColorModel} of the source
0N/A * @param dstColorModel the <code>ColorModel</code> of the destination
0N/A * @return the <code>CompositeContext</code> object to be used to perform
0N/A * compositing operations.
0N/A */
0N/A public CompositeContext createContext(ColorModel srcColorModel,
0N/A ColorModel dstColorModel,
0N/A RenderingHints hints) {
0N/A return new SunCompositeContext(this, srcColorModel, dstColorModel);
0N/A }
0N/A
0N/A /**
0N/A * Returns the alpha value of this <code>AlphaComposite</code>. If this
0N/A * <code>AlphaComposite</code> does not have an alpha value, 1.0 is returned.
0N/A * @return the alpha value of this <code>AlphaComposite</code>.
0N/A */
0N/A public float getAlpha() {
0N/A return extraAlpha;
0N/A }
0N/A
0N/A /**
0N/A * Returns the compositing rule of this <code>AlphaComposite</code>.
0N/A * @return the compositing rule of this <code>AlphaComposite</code>.
0N/A */
0N/A public int getRule() {
0N/A return rule;
0N/A }
0N/A
0N/A /**
0N/A * Returns a similar <code>AlphaComposite</code> object that uses
0N/A * the specified compositing rule.
0N/A * If this object already uses the specified compositing rule,
0N/A * this object is returned.
0N/A * @return an <code>AlphaComposite</code> object derived from
0N/A * this object that uses the specified compositing rule.
0N/A * @param rule the compositing rule
0N/A * @throws IllegalArgumentException if
0N/A * <code>rule</code> is not one of
0N/A * the following: {@link #CLEAR}, {@link #SRC}, {@link #DST},
0N/A * {@link #SRC_OVER}, {@link #DST_OVER}, {@link #SRC_IN},
0N/A * {@link #DST_IN}, {@link #SRC_OUT}, {@link #DST_OUT},
0N/A * {@link #SRC_ATOP}, {@link #DST_ATOP}, or {@link #XOR}
0N/A * @since 1.6
0N/A */
0N/A public AlphaComposite derive(int rule) {
0N/A return (this.rule == rule)
0N/A ? this
0N/A : getInstance(rule, this.extraAlpha);
0N/A }
0N/A
0N/A /**
0N/A * Returns a similar <code>AlphaComposite</code> object that uses
0N/A * the specified alpha value.
0N/A * If this object already has the specified alpha value,
0N/A * this object is returned.
0N/A * @return an <code>AlphaComposite</code> object derived from
0N/A * this object that uses the specified alpha value.
0N/A * @param alpha the constant alpha to be multiplied with the alpha of
0N/A * the source. <code>alpha</code> must be a floating point number in the
0N/A * inclusive range [0.0,&nbsp;1.0].
0N/A * @throws IllegalArgumentException if
0N/A * <code>alpha</code> is less than 0.0 or greater than 1.0
0N/A * @since 1.6
0N/A */
0N/A public AlphaComposite derive(float alpha) {
0N/A return (this.extraAlpha == alpha)
0N/A ? this
0N/A : getInstance(this.rule, alpha);
0N/A }
0N/A
0N/A /**
0N/A * Returns the hashcode for this composite.
0N/A * @return a hash code for this composite.
0N/A */
0N/A public int hashCode() {
0N/A return (Float.floatToIntBits(extraAlpha) * 31 + rule);
0N/A }
0N/A
0N/A /**
0N/A * Determines whether the specified object is equal to this
0N/A * <code>AlphaComposite</code>.
0N/A * <p>
0N/A * The result is <code>true</code> if and only if
0N/A * the argument is not <code>null</code> and is an
0N/A * <code>AlphaComposite</code> object that has the same
0N/A * compositing rule and alpha value as this object.
0N/A *
0N/A * @param obj the <code>Object</code> to test for equality
0N/A * @return <code>true</code> if <code>obj</code> equals this
0N/A * <code>AlphaComposite</code>; <code>false</code> otherwise.
0N/A */
0N/A public boolean equals(Object obj) {
0N/A if (!(obj instanceof AlphaComposite)) {
0N/A return false;
0N/A }
0N/A
0N/A AlphaComposite ac = (AlphaComposite) obj;
0N/A
0N/A if (rule != ac.rule) {
0N/A return false;
0N/A }
0N/A
0N/A if (extraAlpha != ac.extraAlpha) {
0N/A return false;
0N/A }
0N/A
0N/A return true;
0N/A }
0N/A
0N/A}