001: /*
002: * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package java.awt;
027:
028: import java.awt.image.ColorModel;
029: import sun.java2d.SunCompositeContext;
030:
031: /**
032: * The <code>AlphaComposite</code> class implements basic alpha
033: * compositing rules for combining source and destination colors
034: * to achieve blending and transparency effects with graphics and
035: * images.
036: * The specific rules implemented by this class are the basic set
037: * of 12 rules described in
038: * T. Porter and T. Duff, "Compositing Digital Images", SIGGRAPH 84,
039: * 253-259.
040: * The rest of this documentation assumes some familiarity with the
041: * definitions and concepts outlined in that paper.
042: *
043: * <p>
044: * This class extends the standard equations defined by Porter and
045: * Duff to include one additional factor.
046: * An instance of the <code>AlphaComposite</code> class can contain
047: * an alpha value that is used to modify the opacity or coverage of
048: * every source pixel before it is used in the blending equations.
049: *
050: * <p>
051: * It is important to note that the equations defined by the Porter
052: * and Duff paper are all defined to operate on color components
053: * that are premultiplied by their corresponding alpha components.
054: * Since the <code>ColorModel</code> and <code>Raster</code> classes
055: * allow the storage of pixel data in either premultiplied or
056: * non-premultiplied form, all input data must be normalized into
057: * premultiplied form before applying the equations and all results
058: * might need to be adjusted back to the form required by the destination
059: * before the pixel values are stored.
060: *
061: * <p>
062: * Also note that this class defines only the equations
063: * for combining color and alpha values in a purely mathematical
064: * sense. The accurate application of its equations depends
065: * on the way the data is retrieved from its sources and stored
066: * in its destinations.
067: * See <a href="#caveats">Implementation Caveats</a>
068: * for further information.
069: *
070: * <p>
071: * The following factors are used in the description of the blending
072: * equation in the Porter and Duff paper:
073: *
074: * <blockquote>
075: * <table summary="layout">
076: * <tr><th align=left>Factor <th align=left>Definition
077: * <tr><td><em>A<sub>s</sub></em><td>the alpha component of the source pixel
078: * <tr><td><em>C<sub>s</sub></em><td>a color component of the source pixel in premultiplied form
079: * <tr><td><em>A<sub>d</sub></em><td>the alpha component of the destination pixel
080: * <tr><td><em>C<sub>d</sub></em><td>a color component of the destination pixel in premultiplied form
081: * <tr><td><em>F<sub>s</sub></em><td>the fraction of the source pixel that contributes to the output
082: * <tr><td><em>F<sub>d</sub></em><td>the fraction of the destination pixel that contributes
083: * to the output
084: * <tr><td><em>A<sub>r</sub></em><td>the alpha component of the result
085: * <tr><td><em>C<sub>r</sub></em><td>a color component of the result in premultiplied form
086: * </table>
087: * </blockquote>
088: *
089: * <p>
090: * Using these factors, Porter and Duff define 12 ways of choosing
091: * the blending factors <em>F<sub>s</sub></em> and <em>F<sub>d</sub></em> to
092: * produce each of 12 desirable visual effects.
093: * The equations for determining <em>F<sub>s</sub></em> and <em>F<sub>d</sub></em>
094: * are given in the descriptions of the 12 static fields
095: * that specify visual effects.
096: * For example,
097: * the description for
098: * <a href="#SRC_OVER"><code>SRC_OVER</code></a>
099: * specifies that <em>F<sub>s</sub></em> = 1 and <em>F<sub>d</sub></em> = (1-<em>A<sub>s</sub></em>).
100: * Once a set of equations for determining the blending factors is
101: * known they can then be applied to each pixel to produce a result
102: * using the following set of equations:
103: *
104: * <pre>
105: * <em>F<sub>s</sub></em> = <em>f</em>(<em>A<sub>d</sub></em>)
106: * <em>F<sub>d</sub></em> = <em>f</em>(<em>A<sub>s</sub></em>)
107: * <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>
108: * <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>
109: *
110: * <p>
111: * The following factors will be used to discuss our extensions to
112: * the blending equation in the Porter and Duff paper:
113: *
114: * <blockquote>
115: * <table summary="layout">
116: * <tr><th align=left>Factor <th align=left>Definition
117: * <tr><td><em>C<sub>sr</sub></em> <td>one of the raw color components of the source pixel
118: * <tr><td><em>C<sub>dr</sub></em> <td>one of the raw color components of the destination pixel
119: * <tr><td><em>A<sub>ac</sub></em> <td>the "extra" alpha component from the AlphaComposite instance
120: * <tr><td><em>A<sub>sr</sub></em> <td>the raw alpha component of the source pixel
121: * <tr><td><em>A<sub>dr</sub></em><td>the raw alpha component of the destination pixel
122: * <tr><td><em>A<sub>df</sub></em> <td>the final alpha component stored in the destination
123: * <tr><td><em>C<sub>df</sub></em> <td>the final raw color component stored in the destination
124: * </table>
125: *</blockquote>
126: *
127: * <h3>Preparing Inputs</h3>
128: *
129: * <p>
130: * The <code>AlphaComposite</code> class defines an additional alpha
131: * value that is applied to the source alpha.
132: * This value is applied as if an implicit SRC_IN rule were first
133: * applied to the source pixel against a pixel with the indicated
134: * alpha by multiplying both the raw source alpha and the raw
135: * source colors by the alpha in the <code>AlphaComposite</code>.
136: * This leads to the following equation for producing the alpha
137: * used in the Porter and Duff blending equation:
138: *
139: * <pre>
140: * <em>A<sub>s</sub></em> = <em>A<sub>sr</sub></em> * <em>A<sub>ac</sub></em> </pre>
141: *
142: * All of the raw source color components need to be multiplied
143: * by the alpha in the <code>AlphaComposite</code> instance.
144: * Additionally, if the source was not in premultiplied form
145: * then the color components also need to be multiplied by the
146: * source alpha.
147: * Thus, the equation for producing the source color components
148: * for the Porter and Duff equation depends on whether the source
149: * pixels are premultiplied or not:
150: *
151: * <pre>
152: * <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)
153: * <em>C<sub>s</sub></em> = <em>C<sub>sr</sub></em> * <em>A<sub>ac</sub></em> (if source is premultiplied) </pre>
154: *
155: * No adjustment needs to be made to the destination alpha:
156: *
157: * <pre>
158: * <em>A<sub>d</sub></em> = <em>A<sub>dr</sub></em> </pre>
159: *
160: * <p>
161: * The destination color components need to be adjusted only if
162: * they are not in premultiplied form:
163: *
164: * <pre>
165: * <em>C<sub>d</sub></em> = <em>C<sub>dr</sub></em> * <em>A<sub>d</sub></em> (if destination is not premultiplied)
166: * <em>C<sub>d</sub></em> = <em>C<sub>dr</sub></em> (if destination is premultiplied) </pre>
167: *
168: * <h3>Applying the Blending Equation</h3>
169: *
170: * <p>
171: * The adjusted <em>A<sub>s</sub></em>, <em>A<sub>d</sub></em>,
172: * <em>C<sub>s</sub></em>, and <em>C<sub>d</sub></em> are used in the standard
173: * Porter and Duff equations to calculate the blending factors
174: * <em>F<sub>s</sub></em> and <em>F<sub>d</sub></em> and then the resulting
175: * premultiplied components <em>A<sub>r</sub></em> and <em>C<sub>r</sub></em>.
176: *
177: * <p>
178: * <h3>Preparing Results</h3>
179: *
180: * <p>
181: * The results only need to be adjusted if they are to be stored
182: * back into a destination buffer that holds data that is not
183: * premultiplied, using the following equations:
184: *
185: * <pre>
186: * <em>A<sub>df</sub></em> = <em>A<sub>r</sub></em>
187: * <em>C<sub>df</sub></em> = <em>C<sub>r</sub></em> (if dest is premultiplied)
188: * <em>C<sub>df</sub></em> = <em>C<sub>r</sub></em> / <em>A<sub>r</sub></em> (if dest is not premultiplied) </pre>
189: *
190: * Note that since the division is undefined if the resulting alpha
191: * is zero, the division in that case is omitted to avoid the "divide
192: * by zero" and the color components are left as
193: * all zeros.
194: *
195: * <p>
196: * <h3>Performance Considerations</h3>
197: *
198: * <p>
199: * For performance reasons, it is preferrable that
200: * <code>Raster</code> objects passed to the <code>compose</code>
201: * method of a {@link CompositeContext} object created by the
202: * <code>AlphaComposite</code> class have premultiplied data.
203: * If either the source <code>Raster</code>
204: * or the destination <code>Raster</code>
205: * is not premultiplied, however,
206: * appropriate conversions are performed before and after the compositing
207: * operation.
208: *
209: * <h3><a name="caveats">Implementation Caveats</a></h3>
210: *
211: * <ul>
212: * <li>
213: * Many sources, such as some of the opaque image types listed
214: * in the <code>BufferedImage</code> class, do not store alpha values
215: * for their pixels. Such sources supply an alpha of 1.0 for
216: * all of their pixels.
217: *
218: * <p>
219: * <li>
220: * Many destinations also have no place to store the alpha values
221: * that result from the blending calculations performed by this class.
222: * Such destinations thus implicitly discard the resulting
223: * alpha values that this class produces.
224: * It is recommended that such destinations should treat their stored
225: * color values as non-premultiplied and divide the resulting color
226: * values by the resulting alpha value before storing the color
227: * values and discarding the alpha value.
228: *
229: * <p>
230: * <li>
231: * The accuracy of the results depends on the manner in which pixels
232: * are stored in the destination.
233: * An image format that provides at least 8 bits of storage per color
234: * and alpha component is at least adequate for use as a destination
235: * for a sequence of a few to a dozen compositing operations.
236: * An image format with fewer than 8 bits of storage per component
237: * is of limited use for just one or two compositing operations
238: * before the rounding errors dominate the results.
239: * An image format
240: * that does not separately store
241: * color components is not a
242: * good candidate for any type of translucent blending.
243: * For example, <code>BufferedImage.TYPE_BYTE_INDEXED</code>
244: * should not be used as a destination for a blending operation
245: * because every operation
246: * can introduce large errors, due to
247: * the need to choose a pixel from a limited palette to match the
248: * results of the blending equations.
249: *
250: * <p>
251: * <li>
252: * Nearly all formats store pixels as discrete integers rather than
253: * the floating point values used in the reference equations above.
254: * The implementation can either scale the integer pixel
255: * values into floating point values in the range 0.0 to 1.0 or
256: * use slightly modified versions of the equations
257: * that operate entirely in the integer domain and yet produce
258: * analogous results to the reference equations.
259: *
260: * <p>
261: * Typically the integer values are related to the floating point
262: * values in such a way that the integer 0 is equated
263: * to the floating point value 0.0 and the integer
264: * 2^<em>n</em>-1 (where <em>n</em> is the number of bits
265: * in the representation) is equated to 1.0.
266: * For 8-bit representations, this means that 0x00
267: * represents 0.0 and 0xff represents
268: * 1.0.
269: *
270: * <p>
271: * <li>
272: * The internal implementation can approximate some of the equations
273: * and it can also eliminate some steps to avoid unnecessary operations.
274: * For example, consider a discrete integer image with non-premultiplied
275: * alpha values that uses 8 bits per component for storage.
276: * The stored values for a
277: * nearly transparent darkened red might be:
278: *
279: * <pre>
280: * (A, R, G, B) = (0x01, 0xb0, 0x00, 0x00)</pre>
281: *
282: * <p>
283: * If integer math were being used and this value were being
284: * composited in
285: * <a href="#SRC"><code>SRC</code></a>
286: * mode with no extra alpha, then the math would
287: * indicate that the results were (in integer format):
288: *
289: * <pre>
290: * (A, R, G, B) = (0x01, 0x01, 0x00, 0x00)</pre>
291: *
292: * <p>
293: * Note that the intermediate values, which are always in premultiplied
294: * form, would only allow the integer red component to be either 0x00
295: * or 0x01. When we try to store this result back into a destination
296: * that is not premultiplied, dividing out the alpha will give us
297: * very few choices for the non-premultiplied red value.
298: * In this case an implementation that performs the math in integer
299: * space without shortcuts is likely to end up with the final pixel
300: * values of:
301: *
302: * <pre>
303: * (A, R, G, B) = (0x01, 0xff, 0x00, 0x00)</pre>
304: *
305: * <p>
306: * (Note that 0x01 divided by 0x01 gives you 1.0, which is equivalent
307: * to the value 0xff in an 8-bit storage format.)
308: *
309: * <p>
310: * Alternately, an implementation that uses floating point math
311: * might produce more accurate results and end up returning to the
312: * original pixel value with little, if any, roundoff error.
313: * Or, an implementation using integer math might decide that since
314: * the equations boil down to a virtual NOP on the color values
315: * if performed in a floating point space, it can transfer the
316: * pixel untouched to the destination and avoid all the math entirely.
317: *
318: * <p>
319: * These implementations all attempt to honor the
320: * same equations, but use different tradeoffs of integer and
321: * floating point math and reduced or full equations.
322: * To account for such differences, it is probably best to
323: * expect only that the premultiplied form of the results to
324: * match between implementations and image formats. In this
325: * case both answers, expressed in premultiplied form would
326: * equate to:
327: *
328: * <pre>
329: * (A, R, G, B) = (0x01, 0x01, 0x00, 0x00)</pre>
330: *
331: * <p>
332: * and thus they would all match.
333: *
334: * <p>
335: * <li>
336: * Because of the technique of simplifying the equations for
337: * calculation efficiency, some implementations might perform
338: * differently when encountering result alpha values of 0.0
339: * on a non-premultiplied destination.
340: * Note that the simplification of removing the divide by alpha
341: * in the case of the SRC rule is technically not valid if the
342: * denominator (alpha) is 0.
343: * But, since the results should only be expected to be accurate
344: * when viewed in premultiplied form, a resulting alpha of 0
345: * essentially renders the resulting color components irrelevant
346: * and so exact behavior in this case should not be expected.
347: * </ul>
348: * @see Composite
349: * @see CompositeContext
350: * @version 10 Feb 1997
351: */
352:
353: public final class AlphaComposite implements Composite {
354: /**
355: * Both the color and the alpha of the destination are cleared
356: * (Porter-Duff Clear rule).
357: * Neither the source nor the destination is used as input.
358: *<p>
359: * <em>F<sub>s</sub></em> = 0 and <em>F<sub>d</sub></em> = 0, thus:
360: *<pre>
361: * <em>A<sub>r</sub></em> = 0
362: * <em>C<sub>r</sub></em> = 0
363: *</pre>
364: */
365: public static final int CLEAR = 1;
366:
367: /**
368: * The source is copied to the destination
369: * (Porter-Duff Source rule).
370: * The destination is not used as input.
371: *<p>
372: * <em>F<sub>s</sub></em> = 1 and <em>F<sub>d</sub></em> = 0, thus:
373: *<pre>
374: * <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>
375: * <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>
376: *</pre>
377: */
378: public static final int SRC = 2;
379:
380: /**
381: * The destination is left untouched
382: * (Porter-Duff Destination rule).
383: *<p>
384: * <em>F<sub>s</sub></em> = 0 and <em>F<sub>d</sub></em> = 1, thus:
385: *<pre>
386: * <em>A<sub>r</sub></em> = <em>A<sub>d</sub></em>
387: * <em>C<sub>r</sub></em> = <em>C<sub>d</sub></em>
388: *</pre>
389: * @since 1.4
390: */
391: public static final int DST = 9;
392: // Note that DST was added in 1.4 so it is numbered out of order...
393:
394: /**
395: * The source is composited over the destination
396: * (Porter-Duff Source Over Destination rule).
397: *<p>
398: * <em>F<sub>s</sub></em> = 1 and <em>F<sub>d</sub></em> = (1-<em>A<sub>s</sub></em>), thus:
399: *<pre>
400: * <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>)
401: * <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>)
402: *</pre>
403: */
404: public static final int SRC_OVER = 3;
405:
406: /**
407: * The destination is composited over the source and
408: * the result replaces the destination
409: * (Porter-Duff Destination Over Source rule).
410: *<p>
411: * <em>F<sub>s</sub></em> = (1-<em>A<sub>d</sub></em>) and <em>F<sub>d</sub></em> = 1, thus:
412: *<pre>
413: * <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>
414: * <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>
415: *</pre>
416: */
417: public static final int DST_OVER = 4;
418:
419: /**
420: * The part of the source lying inside of the destination replaces
421: * the destination
422: * (Porter-Duff Source In Destination rule).
423: *<p>
424: * <em>F<sub>s</sub></em> = <em>A<sub>d</sub></em> and <em>F<sub>d</sub></em> = 0, thus:
425: *<pre>
426: * <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>*<em>A<sub>d</sub></em>
427: * <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>*<em>A<sub>d</sub></em>
428: *</pre>
429: */
430: public static final int SRC_IN = 5;
431:
432: /**
433: * The part of the destination lying inside of the source
434: * replaces the destination
435: * (Porter-Duff Destination In Source rule).
436: *<p>
437: * <em>F<sub>s</sub></em> = 0 and <em>F<sub>d</sub></em> = <em>A<sub>s</sub></em>, thus:
438: *<pre>
439: * <em>A<sub>r</sub></em> = <em>A<sub>d</sub></em>*<em>A<sub>s</sub></em>
440: * <em>C<sub>r</sub></em> = <em>C<sub>d</sub></em>*<em>A<sub>s</sub></em>
441: *</pre>
442: */
443: public static final int DST_IN = 6;
444:
445: /**
446: * The part of the source lying outside of the destination
447: * replaces the destination
448: * (Porter-Duff Source Held Out By Destination rule).
449: *<p>
450: * <em>F<sub>s</sub></em> = (1-<em>A<sub>d</sub></em>) and <em>F<sub>d</sub></em> = 0, thus:
451: *<pre>
452: * <em>A<sub>r</sub></em> = <em>A<sub>s</sub></em>*(1-<em>A<sub>d</sub></em>)
453: * <em>C<sub>r</sub></em> = <em>C<sub>s</sub></em>*(1-<em>A<sub>d</sub></em>)
454: *</pre>
455: */
456: public static final int SRC_OUT = 7;
457:
458: /**
459: * The part of the destination lying outside of the source
460: * replaces the destination
461: * (Porter-Duff Destination Held Out By Source rule).
462: *<p>
463: * <em>F<sub>s</sub></em> = 0 and <em>F<sub>d</sub></em> = (1-<em>A<sub>s</sub></em>), thus:
464: *<pre>
465: * <em>A<sub>r</sub></em> = <em>A<sub>d</sub></em>*(1-<em>A<sub>s</sub></em>)
466: * <em>C<sub>r</sub></em> = <em>C<sub>d</sub></em>*(1-<em>A<sub>s</sub></em>)
467: *</pre>
468: */
469: public static final int DST_OUT = 8;
470:
471: // Rule 9 is DST which is defined above where it fits into the
472: // list logically, rather than numerically
473: //
474: // public static final int DST = 9;
475:
476: /**
477: * The part of the source lying inside of the destination
478: * is composited onto the destination
479: * (Porter-Duff Source Atop Destination rule).
480: *<p>
481: * <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:
482: *<pre>
483: * <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>
484: * <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>)
485: *</pre>
486: * @since 1.4
487: */
488: public static final int SRC_ATOP = 10;
489:
490: /**
491: * The part of the destination lying inside of the source
492: * is composited over the source and replaces the destination
493: * (Porter-Duff Destination Atop Source rule).
494: *<p>
495: * <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:
496: *<pre>
497: * <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>
498: * <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>
499: *</pre>
500: * @since 1.4
501: */
502: public static final int DST_ATOP = 11;
503:
504: /**
505: * The part of the source that lies outside of the destination
506: * is combined with the part of the destination that lies outside
507: * of the source
508: * (Porter-Duff Source Xor Destination rule).
509: *<p>
510: * <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:
511: *<pre>
512: * <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>)
513: * <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>)
514: *</pre>
515: * @since 1.4
516: */
517: public static final int XOR = 12;
518:
519: /**
520: * <code>AlphaComposite</code> object that implements the opaque CLEAR rule
521: * with an alpha of 1.0f.
522: * @see #CLEAR
523: */
524: public static final AlphaComposite Clear = new AlphaComposite(CLEAR);
525:
526: /**
527: * <code>AlphaComposite</code> object that implements the opaque SRC rule
528: * with an alpha of 1.0f.
529: * @see #SRC
530: */
531: public static final AlphaComposite Src = new AlphaComposite(SRC);
532:
533: /**
534: * <code>AlphaComposite</code> object that implements the opaque DST rule
535: * with an alpha of 1.0f.
536: * @see #DST
537: * @since 1.4
538: */
539: public static final AlphaComposite Dst = new AlphaComposite(DST);
540:
541: /**
542: * <code>AlphaComposite</code> object that implements the opaque SRC_OVER rule
543: * with an alpha of 1.0f.
544: * @see #SRC_OVER
545: */
546: public static final AlphaComposite SrcOver = new AlphaComposite(
547: SRC_OVER);
548:
549: /**
550: * <code>AlphaComposite</code> object that implements the opaque DST_OVER rule
551: * with an alpha of 1.0f.
552: * @see #DST_OVER
553: */
554: public static final AlphaComposite DstOver = new AlphaComposite(
555: DST_OVER);
556:
557: /**
558: * <code>AlphaComposite</code> object that implements the opaque SRC_IN rule
559: * with an alpha of 1.0f.
560: * @see #SRC_IN
561: */
562: public static final AlphaComposite SrcIn = new AlphaComposite(
563: SRC_IN);
564:
565: /**
566: * <code>AlphaComposite</code> object that implements the opaque DST_IN rule
567: * with an alpha of 1.0f.
568: * @see #DST_IN
569: */
570: public static final AlphaComposite DstIn = new AlphaComposite(
571: DST_IN);
572:
573: /**
574: * <code>AlphaComposite</code> object that implements the opaque SRC_OUT rule
575: * with an alpha of 1.0f.
576: * @see #SRC_OUT
577: */
578: public static final AlphaComposite SrcOut = new AlphaComposite(
579: SRC_OUT);
580:
581: /**
582: * <code>AlphaComposite</code> object that implements the opaque DST_OUT rule
583: * with an alpha of 1.0f.
584: * @see #DST_OUT
585: */
586: public static final AlphaComposite DstOut = new AlphaComposite(
587: DST_OUT);
588:
589: /**
590: * <code>AlphaComposite</code> object that implements the opaque SRC_ATOP rule
591: * with an alpha of 1.0f.
592: * @see #SRC_ATOP
593: * @since 1.4
594: */
595: public static final AlphaComposite SrcAtop = new AlphaComposite(
596: SRC_ATOP);
597:
598: /**
599: * <code>AlphaComposite</code> object that implements the opaque DST_ATOP rule
600: * with an alpha of 1.0f.
601: * @see #DST_ATOP
602: * @since 1.4
603: */
604: public static final AlphaComposite DstAtop = new AlphaComposite(
605: DST_ATOP);
606:
607: /**
608: * <code>AlphaComposite</code> object that implements the opaque XOR rule
609: * with an alpha of 1.0f.
610: * @see #XOR
611: * @since 1.4
612: */
613: public static final AlphaComposite Xor = new AlphaComposite(XOR);
614:
615: private static final int MIN_RULE = CLEAR;
616: private static final int MAX_RULE = XOR;
617:
618: float extraAlpha;
619: int rule;
620:
621: private AlphaComposite(int rule) {
622: this (rule, 1.0f);
623: }
624:
625: private AlphaComposite(int rule, float alpha) {
626: if (alpha < 0.0f || alpha > 1.0f) {
627: throw new IllegalArgumentException(
628: "alpha value out of range");
629: }
630: if (rule < MIN_RULE || rule > MAX_RULE) {
631: throw new IllegalArgumentException("unknown composite rule");
632: }
633: this .rule = rule;
634: this .extraAlpha = alpha;
635: }
636:
637: /**
638: * Creates an <code>AlphaComposite</code> object with the specified rule.
639: * @param rule the compositing rule
640: * @throws IllegalArgumentException if <code>rule</code> is not one of
641: * the following: {@link #CLEAR}, {@link #SRC}, {@link #DST},
642: * {@link #SRC_OVER}, {@link #DST_OVER}, {@link #SRC_IN},
643: * {@link #DST_IN}, {@link #SRC_OUT}, {@link #DST_OUT},
644: * {@link #SRC_ATOP}, {@link #DST_ATOP}, or {@link #XOR}
645: */
646: public static AlphaComposite getInstance(int rule) {
647: switch (rule) {
648: case CLEAR:
649: return Clear;
650: case SRC:
651: return Src;
652: case DST:
653: return Dst;
654: case SRC_OVER:
655: return SrcOver;
656: case DST_OVER:
657: return DstOver;
658: case SRC_IN:
659: return SrcIn;
660: case DST_IN:
661: return DstIn;
662: case SRC_OUT:
663: return SrcOut;
664: case DST_OUT:
665: return DstOut;
666: case SRC_ATOP:
667: return SrcAtop;
668: case DST_ATOP:
669: return DstAtop;
670: case XOR:
671: return Xor;
672: default:
673: throw new IllegalArgumentException("unknown composite rule");
674: }
675: }
676:
677: /**
678: * Creates an <code>AlphaComposite</code> object with the specified rule and
679: * the constant alpha to multiply with the alpha of the source.
680: * The source is multiplied with the specified alpha before being composited
681: * with the destination.
682: * @param rule the compositing rule
683: * @param alpha the constant alpha to be multiplied with the alpha of
684: * the source. <code>alpha</code> must be a floating point number in the
685: * inclusive range [0.0, 1.0].
686: * @throws IllegalArgumentException if
687: * <code>alpha</code> is less than 0.0 or greater than 1.0, or if
688: * <code>rule</code> is not one of
689: * the following: {@link #CLEAR}, {@link #SRC}, {@link #DST},
690: * {@link #SRC_OVER}, {@link #DST_OVER}, {@link #SRC_IN},
691: * {@link #DST_IN}, {@link #SRC_OUT}, {@link #DST_OUT},
692: * {@link #SRC_ATOP}, {@link #DST_ATOP}, or {@link #XOR}
693: */
694: public static AlphaComposite getInstance(int rule, float alpha) {
695: if (alpha == 1.0f) {
696: return getInstance(rule);
697: }
698: return new AlphaComposite(rule, alpha);
699: }
700:
701: /**
702: * Creates a context for the compositing operation.
703: * The context contains state that is used in performing
704: * the compositing operation.
705: * @param srcColorModel the {@link ColorModel} of the source
706: * @param dstColorModel the <code>ColorModel</code> of the destination
707: * @return the <code>CompositeContext</code> object to be used to perform
708: * compositing operations.
709: */
710: public CompositeContext createContext(ColorModel srcColorModel,
711: ColorModel dstColorModel, RenderingHints hints) {
712: return new SunCompositeContext(this , srcColorModel,
713: dstColorModel);
714: }
715:
716: /**
717: * Returns the alpha value of this <code>AlphaComposite</code>. If this
718: * <code>AlphaComposite</code> does not have an alpha value, 1.0 is returned.
719: * @return the alpha value of this <code>AlphaComposite</code>.
720: */
721: public float getAlpha() {
722: return extraAlpha;
723: }
724:
725: /**
726: * Returns the compositing rule of this <code>AlphaComposite</code>.
727: * @return the compositing rule of this <code>AlphaComposite</code>.
728: */
729: public int getRule() {
730: return rule;
731: }
732:
733: /**
734: * Returns a similar <code>AlphaComposite</code> object that uses
735: * the specified compositing rule.
736: * If this object already uses the specified compositing rule,
737: * this object is returned.
738: * @return an <code>AlphaComposite</code> object derived from
739: * this object that uses the specified compositing rule.
740: * @param rule the compositing rule
741: * @throws IllegalArgumentException if
742: * <code>rule</code> is not one of
743: * the following: {@link #CLEAR}, {@link #SRC}, {@link #DST},
744: * {@link #SRC_OVER}, {@link #DST_OVER}, {@link #SRC_IN},
745: * {@link #DST_IN}, {@link #SRC_OUT}, {@link #DST_OUT},
746: * {@link #SRC_ATOP}, {@link #DST_ATOP}, or {@link #XOR}
747: * @since 1.6
748: */
749: public AlphaComposite derive(int rule) {
750: return (this .rule == rule) ? this : getInstance(rule,
751: this .extraAlpha);
752: }
753:
754: /**
755: * Returns a similar <code>AlphaComposite</code> object that uses
756: * the specified alpha value.
757: * If this object already has the specified alpha value,
758: * this object is returned.
759: * @return an <code>AlphaComposite</code> object derived from
760: * this object that uses the specified alpha value.
761: * @param alpha the constant alpha to be multiplied with the alpha of
762: * the source. <code>alpha</code> must be a floating point number in the
763: * inclusive range [0.0, 1.0].
764: * @throws IllegalArgumentException if
765: * <code>alpha</code> is less than 0.0 or greater than 1.0
766: * @since 1.6
767: */
768: public AlphaComposite derive(float alpha) {
769: return (this .extraAlpha == alpha) ? this : getInstance(
770: this .rule, alpha);
771: }
772:
773: /**
774: * Returns the hashcode for this composite.
775: * @return a hash code for this composite.
776: */
777: public int hashCode() {
778: return (Float.floatToIntBits(extraAlpha) * 31 + rule);
779: }
780:
781: /**
782: * Determines whether the specified object is equal to this
783: * <code>AlphaComposite</code>.
784: * <p>
785: * The result is <code>true</code> if and only if
786: * the argument is not <code>null</code> and is an
787: * <code>AlphaComposite</code> object that has the same
788: * compositing rule and alpha value as this object.
789: *
790: * @param obj the <code>Object</code> to test for equality
791: * @return <code>true</code> if <code>obj</code> equals this
792: * <code>AlphaComposite</code>; <code>false</code> otherwise.
793: */
794: public boolean equals(Object obj) {
795: if (!(obj instanceof AlphaComposite)) {
796: return false;
797: }
798:
799: AlphaComposite ac = (AlphaComposite) obj;
800:
801: if (rule != ac.rule) {
802: return false;
803: }
804:
805: if (extraAlpha != ac.extraAlpha) {
806: return false;
807: }
808:
809: return true;
810: }
811:
812: }
|