1. /*
  2. * @(#)AlphaComposite.java 1.36 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.awt;
  8. import java.awt.image.ColorModel;
  9. /**
  10. * This <code>AlphaComposite</code> class implements the basic alpha
  11. * compositing rules for combining source and destination pixels to achieve
  12. * blending and transparency effects with graphics and images.
  13. * The rules implemented by this class are a subset of the Porter-Duff
  14. * rules described in
  15. * T. Porter and T. Duff, "Compositing Digital Images", SIGGRAPH 84,
  16. * 253-259.
  17. *<p>
  18. * If any input does not have an alpha channel, an alpha value of 1.0,
  19. * which is completely opaque, is assumed for all pixels. A constant
  20. * alpha value can also be specified to be multiplied with the alpha
  21. * value of the source pixels.
  22. * <p>
  23. * The following abbreviations are used in the description of the rules:
  24. * <ul>
  25. * <li>Cs = one of the color components of the source pixel.
  26. * <li>Cd = one of the color components of the destination pixel.
  27. * <li>As = alpha component of the source pixel.
  28. * <li>Ad = alpha component of the destination pixel.
  29. * <li>Fs = fraction of the source pixel that contributes to the output.
  30. * <li>Fd = fraction of the input destination pixel that contributes to the
  31. * output.
  32. * </ul>
  33. *<p>
  34. * The color and alpha components produced by the compositing operation are
  35. * calculated as follows:
  36. *<pre>
  37. * Cd = Cs*Fs + Cd*Fd
  38. * Ad = As*Fs + Ad*Fd
  39. *</pre>
  40. * where Fs and Fd are specified by each rule. The above equations assume
  41. * that both source and destination pixels have the color components
  42. * premultiplied by the alpha component. Similarly, the equations expressed
  43. * in the definitions of compositing rules below assume premultiplied alpha.
  44. *<p>
  45. * For performance reasons, it is preferrable that Rasters passed to the compose
  46. * method of a {@link CompositeContext} object created by the
  47. * <code>AlphaComposite</code> class have premultiplied data.
  48. * If either source or destination Rasters are not premultiplied, however,
  49. * appropriate conversions are performed before and after the compositing
  50. * operation.
  51. *<p>
  52. * The alpha resulting from the compositing operation is stored
  53. * in the destination if the destination has an alpha channel.
  54. * Otherwise, the resulting color is divided by the resulting
  55. * alpha before being stored in the destination and the alpha is discarded.
  56. * If the alpha value is 0.0, the color values are set to 0.0.
  57. * @see Composite
  58. * @see CompositeContext
  59. * @version 10 Feb 1997
  60. */
  61. public final class AlphaComposite implements Composite {
  62. /**
  63. * Porter-Duff Clear rule.
  64. * Both the color and the alpha of the destination are cleared.
  65. * Neither the source nor the destination is used as input.
  66. *<p>
  67. * Fs = 0 and Fd = 0, thus:
  68. *<pre>
  69. * Cd = 0
  70. * Ad = 0
  71. *</pre>
  72. *
  73. */
  74. public static final int CLEAR = 1;
  75. /**
  76. * Porter-Duff Source rule.
  77. * The source is copied to the destination.
  78. * The destination is not used as input.
  79. *<p>
  80. * Fs = 1 and Fd = 0, thus:
  81. *<pre>
  82. * Cd = Cs
  83. * Ad = As
  84. *</pre>
  85. */
  86. public static final int SRC = 2;
  87. /**
  88. * Porter-Duff Source Over Destination rule.
  89. * The source is composited over the destination.
  90. *<p>
  91. * Fs = 1 and Fd = (1-As), thus:
  92. *<pre>
  93. * Cd = Cs + Cd*(1-As)
  94. * Ad = As + Ad*(1-As)
  95. *</pre>
  96. */
  97. public static final int SRC_OVER = 3;
  98. /**
  99. * Porter-Duff Destination Over Source rule.
  100. * The destination is composited over the source and
  101. * the result replaces the destination.
  102. *<p>
  103. * Fs = (1-Ad) and Fd = 1, thus:
  104. *<pre>
  105. * Cd = Cs*(1-Ad) + Cd
  106. * Ad = As*(1-Ad) + Ad
  107. *</pre>
  108. */
  109. public static final int DST_OVER = 4;
  110. /**
  111. * Porter-Duff Source In Destination rule.
  112. * The part of the source lying inside of the destination replaces
  113. * the destination.
  114. *<p>
  115. * Fs = Ad and Fd = 0, thus:
  116. *<pre>
  117. * Cd = Cs*Ad
  118. * Ad = As*Ad
  119. *</pre>
  120. */
  121. public static final int SRC_IN = 5;
  122. /**
  123. * Porter-Duff Destination In Source rule.
  124. * The part of the destination lying inside of the source
  125. * replaces the destination.
  126. *<p>
  127. * Fs = 0 and Fd = As, thus:
  128. *<pre>
  129. * Cd = Cd*As
  130. * Ad = Ad*As
  131. *</pre>
  132. */
  133. public static final int DST_IN = 6;
  134. /**
  135. * Porter-Duff Source Held Out By Destination rule.
  136. * The part of the source lying outside of the destination
  137. * replaces the destination.
  138. *<p>
  139. * Fs = (1-Ad) and Fd = 0, thus:
  140. *<pre>
  141. * Cd = Cs*(1-Ad)
  142. * Ad = As*(1-Ad)
  143. *</pre>
  144. */
  145. public static final int SRC_OUT = 7;
  146. /**
  147. * Porter-Duff Destination Held Out By Source rule.
  148. * The part of the destination lying outside of the source
  149. * replaces the destination.
  150. *<p>
  151. * Fs = 0 and Fd = (1-As), thus:
  152. *<pre>
  153. * Cd = Cd*(1-As)
  154. * Ad = Ad*(1-As)
  155. *</pre>
  156. */
  157. public static final int DST_OUT = 8;
  158. /**
  159. * <code>AlphaComposite</code> object that implements the opaque CLEAR rule
  160. * with an alpha of 1.0f.
  161. * @see #CLEAR
  162. */
  163. public static final AlphaComposite Clear = new AlphaComposite(CLEAR);
  164. /**
  165. * <code>AlphaComposite</code> object that implements the opaque SRC rule
  166. * with an alpha of 1.0f.
  167. * @see #SRC
  168. */
  169. public static final AlphaComposite Src = new AlphaComposite(SRC);
  170. /**
  171. * <code>AlphaComposite</code> object that implements the opaque SRC_OVER rule
  172. * with an alpha of 1.0f.
  173. * @see #SRC_OVER
  174. */
  175. public static final AlphaComposite SrcOver = new AlphaComposite(SRC_OVER);
  176. /**
  177. * <code>AlphaComposite</code> object that implements the opaque DST_OVER rule
  178. * with an alpha of 1.0f.
  179. * @see #DST_OVER
  180. */
  181. public static final AlphaComposite DstOver = new AlphaComposite(DST_OVER);
  182. /**
  183. * <code>AlphaComposite</code> object that implements the opaque SRC_IN rule
  184. * with an alpha of 1.0f.
  185. * @see #SRC_IN
  186. */
  187. public static final AlphaComposite SrcIn = new AlphaComposite(SRC_IN);
  188. /**
  189. * <code>AlphaComposite</code> object that implements the opaque DST_IN rule
  190. * with an alpha of 1.0f.
  191. * @see #DST_IN
  192. */
  193. public static final AlphaComposite DstIn = new AlphaComposite(DST_IN);
  194. /**
  195. * <code>AlphaComposite</code> object that implements the opaque SRC_OUT rule
  196. * with an alpha of 1.0f.
  197. * @see #SRC_OUT
  198. */
  199. public static final AlphaComposite SrcOut = new AlphaComposite(SRC_OUT);
  200. /**
  201. * <code>AlphaComposite</code> object that implements the opaque DST_OUT rule
  202. * with an alpha of 1.0f.
  203. * @see #DST_OUT
  204. */
  205. public static final AlphaComposite DstOut = new AlphaComposite(DST_OUT);
  206. private static final int MIN_RULE = CLEAR;
  207. private static final int MAX_RULE = DST_OUT;
  208. float extraAlpha;
  209. int rule;
  210. private AlphaComposite(int rule) {
  211. this(rule, 1.0f);
  212. }
  213. private AlphaComposite(int rule, float alpha) {
  214. if (alpha < 0.0f || alpha > 1.0f) {
  215. throw new IllegalArgumentException("alpha value out of range");
  216. }
  217. if (rule < MIN_RULE || rule > MAX_RULE) {
  218. throw new IllegalArgumentException("unknown composite rule");
  219. }
  220. this.rule = rule;
  221. this.extraAlpha = alpha;
  222. }
  223. /**
  224. * Creates an <code>AlphaComposite</code> object with the specified rule.
  225. * @param rule the compositing rule
  226. * @throws IllegalArgumentException if <code>rule</code> is not one of
  227. * the following: {@link #CLEAR}, {@link #SRC},
  228. * {@link #SRC_OVER}, {@link #DST_OVER}, {@link #SRC_IN},
  229. * {@link #DST_IN}, {@link #SRC_OUT}, or {@link #DST_OUT}
  230. */
  231. public static AlphaComposite getInstance(int rule) {
  232. switch (rule) {
  233. case CLEAR:
  234. return Clear;
  235. case SRC:
  236. return Src;
  237. case SRC_OVER:
  238. return SrcOver;
  239. case DST_OVER:
  240. return DstOver;
  241. case SRC_IN:
  242. return SrcIn;
  243. case DST_IN:
  244. return DstIn;
  245. case SRC_OUT:
  246. return SrcOut;
  247. case DST_OUT:
  248. return DstOut;
  249. default:
  250. throw new IllegalArgumentException("unknown composite rule");
  251. }
  252. }
  253. /**
  254. * Creates an <code>AlphaComposite</code> object with the specified rule and
  255. * the constant alpha to multiply with the alpha of the source.
  256. * The source is multiplied with the specified alpha before being composited
  257. * with the destination.
  258. * @param rule the compositing rule
  259. * @param alpha the constant alpha to be multiplied with the alpha of
  260. * the source. <code>alpha</code> must be a floating point number in the
  261. * inclusive range [0.0, 1.0].
  262. */
  263. public static AlphaComposite getInstance(int rule, float alpha) {
  264. if (alpha == 1.0f) {
  265. return getInstance(rule);
  266. }
  267. return new AlphaComposite(rule, alpha);
  268. }
  269. /**
  270. * Creates a context for the compositing operation.
  271. * The context contains state that is used in performing
  272. * the compositing operation.
  273. * @param srcColorModel the {@link ColorModel} of the source
  274. * @param dstColorModel the <code>ColorModel</code> of the destination
  275. * @return the <code>CompositeContext</code> object to be used to perform
  276. * compositing operations.
  277. */
  278. public CompositeContext createContext(ColorModel srcColorModel,
  279. ColorModel dstColorModel,
  280. RenderingHints hints) {
  281. return new AlphaCompositeContext(srcColorModel, dstColorModel,
  282. rule, extraAlpha);
  283. }
  284. /**
  285. * Returns the alpha value of this<code>AlphaComposite</code>. If this
  286. * <code>AlphaComposite</code> does not have an alpha value, 1.0 is returned.
  287. * @return the alpha value of this <code>AlphaComposite</code>.
  288. */
  289. public float getAlpha() {
  290. return extraAlpha;
  291. }
  292. /**
  293. * Returns the compositing rule of this <code>AlphaComposite</code>.
  294. * @return the compositing rule of this <code>AlphaComposite</code>.
  295. */
  296. public int getRule() {
  297. return rule;
  298. }
  299. /**
  300. * Returns the hashcode for this composite.
  301. * @return a hash code for this composite.
  302. */
  303. public int hashCode() {
  304. return (Float.floatToIntBits(extraAlpha) * 31 + rule);
  305. }
  306. /**
  307. * Tests if the specified {@link Object} is equal to this
  308. * <code>AlphaComposite</code> object.
  309. * @param obj the <code>Object</code> to test for equality
  310. * @return <code>true</code> if <code>obj</code> equals this
  311. * <code>AlphaComposite</code> <code>false</code> otherwise.
  312. */
  313. public boolean equals(Object obj) {
  314. if (!(obj instanceof AlphaComposite)) {
  315. return false;
  316. }
  317. AlphaComposite ac = (AlphaComposite) obj;
  318. if (rule != ac.rule) {
  319. return false;
  320. }
  321. if (extraAlpha != ac.extraAlpha) {
  322. return false;
  323. }
  324. return true;
  325. }
  326. }