1. /*
  2. * @(#)AlphaComposite.java 1.44 03/01/23
  3. *
  4. * Copyright 2003 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. import sun.java2d.SunCompositeContext;
  10. /**
  11. * This <code>AlphaComposite</code> class implements the basic alpha
  12. * compositing rules for combining source and destination pixels to achieve
  13. * blending and transparency effects with graphics and images.
  14. * The rules implemented by this class are the set of Porter-Duff
  15. * rules described in
  16. * T. Porter and T. Duff, "Compositing Digital Images", SIGGRAPH 84,
  17. * 253-259.
  18. *<p>
  19. * If any input does not have an alpha channel, an alpha value of 1.0,
  20. * which is completely opaque, is assumed for all pixels. A constant
  21. * alpha value can also be specified to be multiplied with the alpha
  22. * value of the source pixels.
  23. * <p>
  24. * The following abbreviations are used in the description of the rules:
  25. * <ul>
  26. * <li>Cs = one of the color components of the source pixel.
  27. * <li>Cd = one of the color components of the destination pixel.
  28. * <li>As = alpha component of the source pixel.
  29. * <li>Ad = alpha component of the destination pixel.
  30. * <li>Fs = fraction of the source pixel that contributes to the output.
  31. * <li>Fd = fraction of the input destination pixel that contributes to the
  32. * output.
  33. * </ul>
  34. *<p>
  35. * The color and alpha components produced by the compositing operation are
  36. * calculated as follows:
  37. *<pre>
  38. * Cd = Cs*Fs + Cd*Fd
  39. * Ad = As*Fs + Ad*Fd
  40. *</pre>
  41. * where Fs and Fd are specified by each rule. The above equations assume
  42. * that both source and destination pixels have the color components
  43. * premultiplied by the alpha component. Similarly, the equations expressed
  44. * in the definitions of compositing rules below assume premultiplied alpha.
  45. *<p>
  46. * For performance reasons, it is preferrable that Rasters passed to the compose
  47. * method of a {@link CompositeContext} object created by the
  48. * <code>AlphaComposite</code> class have premultiplied data.
  49. * If either source or destination Rasters are not premultiplied, however,
  50. * appropriate conversions are performed before and after the compositing
  51. * operation.
  52. *<p>
  53. * The alpha resulting from the compositing operation is stored
  54. * in the destination if the destination has an alpha channel.
  55. * Otherwise, the resulting color is divided by the resulting
  56. * alpha before being stored in the destination and the alpha is discarded.
  57. * If the alpha value is 0.0, the color values are set to 0.0.
  58. * @see Composite
  59. * @see CompositeContext
  60. * @version 10 Feb 1997
  61. */
  62. public final class AlphaComposite implements Composite {
  63. /**
  64. * Porter-Duff Clear rule.
  65. * Both the color and the alpha of the destination are cleared.
  66. * Neither the source nor the destination is used as input.
  67. *<p>
  68. * Fs = 0 and Fd = 0, thus:
  69. *<pre>
  70. * Cd = 0
  71. * Ad = 0
  72. *</pre>
  73. *
  74. */
  75. public static final int CLEAR = 1;
  76. /**
  77. * Porter-Duff Source rule.
  78. * The source is copied to the destination.
  79. * The destination is not used as input.
  80. *<p>
  81. * Fs = 1 and Fd = 0, thus:
  82. *<pre>
  83. * Cd = Cs
  84. * Ad = As
  85. *</pre>
  86. */
  87. public static final int SRC = 2;
  88. /**
  89. * Porter-Duff Destination rule.
  90. * The destination is left untouched.
  91. *<p>
  92. * Fs = 0 and Fd = 1, thus:
  93. *<pre>
  94. * Cd = Cd
  95. * Ad = Ad
  96. *</pre>
  97. * @since 1.4
  98. */
  99. public static final int DST = 9;
  100. // Note that DST was added in 1.4 so it is numbered out of order...
  101. /**
  102. * Porter-Duff Source Over Destination rule.
  103. * The source is composited over the destination.
  104. *<p>
  105. * Fs = 1 and Fd = (1-As), thus:
  106. *<pre>
  107. * Cd = Cs + Cd*(1-As)
  108. * Ad = As + Ad*(1-As)
  109. *</pre>
  110. */
  111. public static final int SRC_OVER = 3;
  112. /**
  113. * Porter-Duff Destination Over Source rule.
  114. * The destination is composited over the source and
  115. * the result replaces the destination.
  116. *<p>
  117. * Fs = (1-Ad) and Fd = 1, thus:
  118. *<pre>
  119. * Cd = Cs*(1-Ad) + Cd
  120. * Ad = As*(1-Ad) + Ad
  121. *</pre>
  122. */
  123. public static final int DST_OVER = 4;
  124. /**
  125. * Porter-Duff Source In Destination rule.
  126. * The part of the source lying inside of the destination replaces
  127. * the destination.
  128. *<p>
  129. * Fs = Ad and Fd = 0, thus:
  130. *<pre>
  131. * Cd = Cs*Ad
  132. * Ad = As*Ad
  133. *</pre>
  134. */
  135. public static final int SRC_IN = 5;
  136. /**
  137. * Porter-Duff Destination In Source rule.
  138. * The part of the destination lying inside of the source
  139. * replaces the destination.
  140. *<p>
  141. * Fs = 0 and Fd = As, thus:
  142. *<pre>
  143. * Cd = Cd*As
  144. * Ad = Ad*As
  145. *</pre>
  146. */
  147. public static final int DST_IN = 6;
  148. /**
  149. * Porter-Duff Source Held Out By Destination rule.
  150. * The part of the source lying outside of the destination
  151. * replaces the destination.
  152. *<p>
  153. * Fs = (1-Ad) and Fd = 0, thus:
  154. *<pre>
  155. * Cd = Cs*(1-Ad)
  156. * Ad = As*(1-Ad)
  157. *</pre>
  158. */
  159. public static final int SRC_OUT = 7;
  160. /**
  161. * Porter-Duff Destination Held Out By Source rule.
  162. * The part of the destination lying outside of the source
  163. * replaces the destination.
  164. *<p>
  165. * Fs = 0 and Fd = (1-As), thus:
  166. *<pre>
  167. * Cd = Cd*(1-As)
  168. * Ad = Ad*(1-As)
  169. *</pre>
  170. */
  171. public static final int DST_OUT = 8;
  172. // Rule 9 is DST which is defined above where it fits into the
  173. // list logically, rather than numerically
  174. //
  175. // public static final int DST = 9;
  176. /**
  177. * Porter-Duff Source Atop Destination rule.
  178. * The part of the source lying inside of the destination
  179. * is composited onto the destination.
  180. *<p>
  181. * Fs = Ad and Fd = (1-As), thus:
  182. *<pre>
  183. * Cd = Cs*Ad + Cd*(1-As)
  184. * Ad = As*Ad + Ad*(1-As) = Ad
  185. *</pre>
  186. * @since 1.4
  187. */
  188. public static final int SRC_ATOP = 10;
  189. /**
  190. * Porter-Duff Destination Atop Source rule.
  191. * The part of the destination lying inside of the source
  192. * is composited over the source and replaces the destination.
  193. *<p>
  194. * Fs = (1-Ad) and Fd = As, thus:
  195. *<pre>
  196. * Cd = Cs*(1-Ad) + Cd*As
  197. * Ad = As*(1-Ad) + Ad*As = As
  198. *</pre>
  199. * @since 1.4
  200. */
  201. public static final int DST_ATOP = 11;
  202. /**
  203. * Porter-Duff Source Xor Destination rule.
  204. * The part of the source that lies outside of the destination
  205. * is combined with the part of the destination that lies outside
  206. * of the source.
  207. *<p>
  208. * Fs = (1-Ad) and Fd = (1-As), thus:
  209. *<pre>
  210. * Cd = Cs*(1-Ad) + Cd*(1-As)
  211. * Ad = As*(1-Ad) + Ad*(1-As)
  212. *</pre>
  213. * @since 1.4
  214. */
  215. public static final int XOR = 12;
  216. /**
  217. * <code>AlphaComposite</code> object that implements the opaque CLEAR rule
  218. * with an alpha of 1.0f.
  219. * @see #CLEAR
  220. */
  221. public static final AlphaComposite Clear = new AlphaComposite(CLEAR);
  222. /**
  223. * <code>AlphaComposite</code> object that implements the opaque SRC rule
  224. * with an alpha of 1.0f.
  225. * @see #SRC
  226. */
  227. public static final AlphaComposite Src = new AlphaComposite(SRC);
  228. /**
  229. * <code>AlphaComposite</code> object that implements the opaque DST rule
  230. * with an alpha of 1.0f.
  231. * @see #DST
  232. * @since 1.4
  233. */
  234. public static final AlphaComposite Dst = new AlphaComposite(DST);
  235. /**
  236. * <code>AlphaComposite</code> object that implements the opaque SRC_OVER rule
  237. * with an alpha of 1.0f.
  238. * @see #SRC_OVER
  239. */
  240. public static final AlphaComposite SrcOver = new AlphaComposite(SRC_OVER);
  241. /**
  242. * <code>AlphaComposite</code> object that implements the opaque DST_OVER rule
  243. * with an alpha of 1.0f.
  244. * @see #DST_OVER
  245. */
  246. public static final AlphaComposite DstOver = new AlphaComposite(DST_OVER);
  247. /**
  248. * <code>AlphaComposite</code> object that implements the opaque SRC_IN rule
  249. * with an alpha of 1.0f.
  250. * @see #SRC_IN
  251. */
  252. public static final AlphaComposite SrcIn = new AlphaComposite(SRC_IN);
  253. /**
  254. * <code>AlphaComposite</code> object that implements the opaque DST_IN rule
  255. * with an alpha of 1.0f.
  256. * @see #DST_IN
  257. */
  258. public static final AlphaComposite DstIn = new AlphaComposite(DST_IN);
  259. /**
  260. * <code>AlphaComposite</code> object that implements the opaque SRC_OUT rule
  261. * with an alpha of 1.0f.
  262. * @see #SRC_OUT
  263. */
  264. public static final AlphaComposite SrcOut = new AlphaComposite(SRC_OUT);
  265. /**
  266. * <code>AlphaComposite</code> object that implements the opaque DST_OUT rule
  267. * with an alpha of 1.0f.
  268. * @see #DST_OUT
  269. */
  270. public static final AlphaComposite DstOut = new AlphaComposite(DST_OUT);
  271. /**
  272. * <code>AlphaComposite</code> object that implements the opaque SRC_ATOP rule
  273. * with an alpha of 1.0f.
  274. * @see #SRC_ATOP
  275. * @since 1.4
  276. */
  277. public static final AlphaComposite SrcAtop = new AlphaComposite(SRC_ATOP);
  278. /**
  279. * <code>AlphaComposite</code> object that implements the opaque DST_ATOP rule
  280. * with an alpha of 1.0f.
  281. * @see #DST_ATOP
  282. * @since 1.4
  283. */
  284. public static final AlphaComposite DstAtop = new AlphaComposite(DST_ATOP);
  285. /**
  286. * <code>AlphaComposite</code> object that implements the opaque XOR rule
  287. * with an alpha of 1.0f.
  288. * @see #XOR
  289. * @since 1.4
  290. */
  291. public static final AlphaComposite Xor = new AlphaComposite(XOR);
  292. private static final int MIN_RULE = CLEAR;
  293. private static final int MAX_RULE = XOR;
  294. float extraAlpha;
  295. int rule;
  296. private AlphaComposite(int rule) {
  297. this(rule, 1.0f);
  298. }
  299. private AlphaComposite(int rule, float alpha) {
  300. if (alpha < 0.0f || alpha > 1.0f) {
  301. throw new IllegalArgumentException("alpha value out of range");
  302. }
  303. if (rule < MIN_RULE || rule > MAX_RULE) {
  304. throw new IllegalArgumentException("unknown composite rule");
  305. }
  306. this.rule = rule;
  307. this.extraAlpha = alpha;
  308. }
  309. /**
  310. * Creates an <code>AlphaComposite</code> object with the specified rule.
  311. * @param rule the compositing rule
  312. * @throws IllegalArgumentException if <code>rule</code> is not one of
  313. * the following: {@link #CLEAR}, {@link #SRC}, {@link #DST},
  314. * {@link #SRC_OVER}, {@link #DST_OVER}, {@link #SRC_IN},
  315. * {@link #DST_IN}, {@link #SRC_OUT}, {@link #DST_OUT},
  316. * {@link #SRC_ATOP}, {@link #DST_ATOP}, or {@link #XOR}
  317. */
  318. public static AlphaComposite getInstance(int rule) {
  319. switch (rule) {
  320. case CLEAR:
  321. return Clear;
  322. case SRC:
  323. return Src;
  324. case DST:
  325. return Dst;
  326. case SRC_OVER:
  327. return SrcOver;
  328. case DST_OVER:
  329. return DstOver;
  330. case SRC_IN:
  331. return SrcIn;
  332. case DST_IN:
  333. return DstIn;
  334. case SRC_OUT:
  335. return SrcOut;
  336. case DST_OUT:
  337. return DstOut;
  338. case SRC_ATOP:
  339. return SrcAtop;
  340. case DST_ATOP:
  341. return DstAtop;
  342. case XOR:
  343. return Xor;
  344. default:
  345. throw new IllegalArgumentException("unknown composite rule");
  346. }
  347. }
  348. /**
  349. * Creates an <code>AlphaComposite</code> object with the specified rule and
  350. * the constant alpha to multiply with the alpha of the source.
  351. * The source is multiplied with the specified alpha before being composited
  352. * with the destination.
  353. * @param rule the compositing rule
  354. * @param alpha the constant alpha to be multiplied with the alpha of
  355. * the source. <code>alpha</code> must be a floating point number in the
  356. * inclusive range [0.0, 1.0].
  357. * @throws IllegalArgumentException if
  358. * <code>alpha</code> is less than 0.0 or greater than 1.0, or if
  359. * <code>rule</code> is not one of
  360. * the following: {@link #CLEAR}, {@link #SRC}, {@link #DST},
  361. * {@link #SRC_OVER}, {@link #DST_OVER}, {@link #SRC_IN},
  362. * {@link #DST_IN}, {@link #SRC_OUT}, {@link #DST_OUT},
  363. * {@link #SRC_ATOP}, {@link #DST_ATOP}, or {@link #XOR}
  364. */
  365. public static AlphaComposite getInstance(int rule, float alpha) {
  366. if (alpha == 1.0f) {
  367. return getInstance(rule);
  368. }
  369. return new AlphaComposite(rule, alpha);
  370. }
  371. /**
  372. * Creates a context for the compositing operation.
  373. * The context contains state that is used in performing
  374. * the compositing operation.
  375. * @param srcColorModel the {@link ColorModel} of the source
  376. * @param dstColorModel the <code>ColorModel</code> of the destination
  377. * @return the <code>CompositeContext</code> object to be used to perform
  378. * compositing operations.
  379. */
  380. public CompositeContext createContext(ColorModel srcColorModel,
  381. ColorModel dstColorModel,
  382. RenderingHints hints) {
  383. return new SunCompositeContext(this, srcColorModel, dstColorModel);
  384. }
  385. /**
  386. * Returns the alpha value of this <code>AlphaComposite</code>. If this
  387. * <code>AlphaComposite</code> does not have an alpha value, 1.0 is returned.
  388. * @return the alpha value of this <code>AlphaComposite</code>.
  389. */
  390. public float getAlpha() {
  391. return extraAlpha;
  392. }
  393. /**
  394. * Returns the compositing rule of this <code>AlphaComposite</code>.
  395. * @return the compositing rule of this <code>AlphaComposite</code>.
  396. */
  397. public int getRule() {
  398. return rule;
  399. }
  400. /**
  401. * Returns the hashcode for this composite.
  402. * @return a hash code for this composite.
  403. */
  404. public int hashCode() {
  405. return (Float.floatToIntBits(extraAlpha) * 31 + rule);
  406. }
  407. /**
  408. * Determines whether the specified object is equal to this
  409. * <code>AlphaComposite</code>.
  410. * <p>
  411. * The result is <code>true</code> if and only if
  412. * the argument is not <code>null</code> and is an
  413. * <code>AlphaComposite</code> object that has the same
  414. * compositing rule and alpha value as this object.
  415. *
  416. * @param obj the <code>Object</code> to test for equality
  417. * @return <code>true</code> if <code>obj</code> equals this
  418. * <code>AlphaComposite</code> <code>false</code> otherwise.
  419. */
  420. public boolean equals(Object obj) {
  421. if (!(obj instanceof AlphaComposite)) {
  422. return false;
  423. }
  424. AlphaComposite ac = (AlphaComposite) obj;
  425. if (rule != ac.rule) {
  426. return false;
  427. }
  428. if (extraAlpha != ac.extraAlpha) {
  429. return false;
  430. }
  431. return true;
  432. }
  433. }