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