1. /*
  2. * @(#)AlphaCompositeContext.java 1.10 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. import java.awt.image.IndexColorModel;
  10. import java.awt.image.BufferedImage;
  11. import java.awt.image.Raster;
  12. import java.awt.image.WritableRaster;
  13. import sun.awt.image.IntegerComponentRaster;
  14. class AlphaCompositeContext implements CompositeContext {
  15. ColorModel srcCM;
  16. ColorModel dstCM;
  17. boolean srcNeedConvert;
  18. boolean dstNeedConvert;
  19. int rule;
  20. float extraAlpha;
  21. public AlphaCompositeContext(ColorModel s, ColorModel d, int rule,
  22. float extraAlpha) {
  23. srcCM = s;
  24. if (srcCM.equals(ColorModel.getRGBdefault())) {
  25. srcNeedConvert = false;
  26. } else {
  27. srcNeedConvert = true;
  28. }
  29. dstCM = d;
  30. if (dstCM.equals(ColorModel.getRGBdefault())) {
  31. dstNeedConvert = false;
  32. } else {
  33. dstNeedConvert = true;
  34. }
  35. this.rule = rule;
  36. this.extraAlpha = extraAlpha;
  37. }
  38. /*
  39. * Convert a given Raster to the desired data format.
  40. */
  41. WritableRaster convertRaster(Raster inRaster, ColorModel inCM, ColorModel outCM) {
  42. // Use a faster conversion if this is an IndexColorModel
  43. if (inCM instanceof IndexColorModel &&
  44. outCM.equals(ColorModel.getRGBdefault())) {
  45. IndexColorModel icm = (IndexColorModel) inCM;
  46. BufferedImage dbi = icm.convertToIntDiscrete(inRaster, false);
  47. return dbi.getRaster();
  48. }
  49. BufferedImage dbi =
  50. new BufferedImage(outCM,
  51. outCM.createCompatibleWritableRaster(inRaster.getWidth(),
  52. inRaster.getHeight()),
  53. outCM.isAlphaPremultiplied(),
  54. null);
  55. // ColorSpace[] cs = {inCM.getColorSpace(), outCM.getColorSpace()};
  56. // ColorConvertOp cOp = new ColorConvertOp(cs);
  57. // cOp.filter(sbi, dbi);
  58. // use this slow method to convert untill ColorConvertOp is available.
  59. // Does not take in to account quality dithering if applicable.
  60. for (int i = 0 ; i < inRaster.getHeight() ; i++) {
  61. for (int j = 0 ; j < inRaster.getWidth() ; j++) {
  62. dbi.setRGB(j, i,
  63. inCM.getRGB(inRaster.getDataElements(j,i,null)));
  64. }
  65. }
  66. return dbi.getRaster();
  67. }
  68. /**
  69. * Release resources allocated for context.
  70. */
  71. public void dispose() {
  72. }
  73. // native void alphaComposite(Raster s, Raster d,
  74. // int width, int height,
  75. // int rule, float extraAlpha);
  76. /**
  77. * This method composes the two source tiles
  78. * and places the result in the destination tile. Note that
  79. * the destination can be the same object as either
  80. * the first or second source.
  81. * @param src1 The first source tile for the compositing operation.
  82. * @param src2 The second source tile for the compositing operation.
  83. * @param dst The tile where the result of the operation is stored.
  84. */
  85. public void compose(Raster src1, Raster src2, WritableRaster dst) {
  86. IntegerComponentRaster s;
  87. IntegerComponentRaster d;
  88. WritableRaster dstOrg = dst;
  89. int w;
  90. int h;
  91. if (srcNeedConvert) {
  92. src1 = convertRaster(src1, srcCM, ColorModel.getRGBdefault());
  93. src2 = convertRaster(src2, srcCM, ColorModel.getRGBdefault());
  94. }
  95. if (dstNeedConvert && !(dst == src1 || dst == src2)) {
  96. dst = convertRaster(dst, dstCM, ColorModel.getRGBdefault());
  97. }
  98. if (dst == src1) {
  99. s = (IntegerComponentRaster)src2;
  100. } else if (dst == src2) {
  101. s = (IntegerComponentRaster)src1;
  102. } else {
  103. dst.setDataElements(0, 0, src2);
  104. s = (IntegerComponentRaster)src1;
  105. }
  106. d = (IntegerComponentRaster)dst;
  107. w = Math.min(s.getWidth(), d.getWidth());
  108. h = Math.min(s.getHeight(), d.getHeight());
  109. // REMIND: May need a wrapper in RasterOutputManager.c to avoid
  110. // reference to sun.awt.image package from here:
  111. // alphaComposite(s, d, w, h, rule, extraAlpha);
  112. sun.java2d.loops.RasterOutputManager.ARGBpaintARGB(s, false, d, rule,
  113. extraAlpha, null,
  114. 0, 0, 0, 0, 0, 0,
  115. w, h, 0);
  116. if (dstNeedConvert) {
  117. dst = convertRaster(dst, ColorModel.getRGBdefault(), dstCM);
  118. dstOrg.setDataElements(0, 0, dst);
  119. }
  120. }
  121. }