1: 
  37: 
  38: 
  39: package ;
  40: 
  41: import ;
  42: import ;
  43: import ;
  44: import ;
  45: import ;
  46: import ;
  47: 
  48: 
  53: public class AlphaCompositeContext
  54:   implements CompositeContext
  55: {
  56: 
  57:   
  60:   private AlphaComposite composite;
  61: 
  62:   
  65:   private ColorModel srcColorModel;
  66: 
  67:   
  70:   private ColorModel dstColorModel;
  71: 
  72:   
  75:   private float fs;
  76: 
  77:   
  80:   private float fd;
  81: 
  82:   
  89:   public AlphaCompositeContext(AlphaComposite aComp, ColorModel srcCM,
  90:                                ColorModel dstCM)
  91:   {
  92:     composite = aComp;
  93:     srcColorModel = srcCM;
  94:     dstColorModel = dstCM;
  95: 
  96: 
  97:     
  98:     
  99:     
 100:     switch (composite.getRule())
 101:     {
 102:       case AlphaComposite.CLEAR:
 103:         fs = 0.F;
 104:         fd= 0.F;
 105:         break;
 106:       case AlphaComposite.DST:
 107:         fs = 0.F;
 108:         fd= 1.F;
 109:         break;
 110:       case AlphaComposite.DST_ATOP:
 111:         fs = 1.F; 
 112:         fd = 1.F; 
 113:         break;
 114:       case AlphaComposite.DST_IN:
 115:         fs = 0.F;
 116:         fd = 0.F; 
 117:         break;
 118:       case AlphaComposite.DST_OUT:
 119:         fs = 0.F;
 120:         fd = 0.F; 
 121:         break;
 122:       case AlphaComposite.DST_OVER:
 123:         fs = 1.F; 
 124:         fd= 1.F;
 125:         break;
 126:       case AlphaComposite.SRC:
 127:         fs = 1.F;
 128:         fd= 0.F;
 129:         break;
 130:       case AlphaComposite.SRC_ATOP:
 131:         fs = 1.F; 
 132:         fd = 1.F; 
 133:         break;
 134:       case AlphaComposite.SRC_IN:
 135:         fs = 0.F; 
 136:         fd = 0.F;
 137:         break;
 138:       case AlphaComposite.SRC_OUT:
 139:         fs = 0.F; 
 140:         fd = 0.F;
 141:         break;
 142:       case AlphaComposite.SRC_OVER:
 143:         fs = 1.F;
 144:         fd= 1.F; 
 145:         break;
 146:       case AlphaComposite.XOR:
 147:         fs = 1.F; 
 148:         fd= 1.F; 
 149:         break;
 150:       default:
 151:         throw new AWTError("Illegal AlphaComposite rule");
 152:     }
 153: 
 154:   }
 155: 
 156:   
 159:   public void dispose()
 160:   {
 161:     
 162:   }
 163: 
 164:   
 168:   public void compose(Raster src, Raster dstIn, WritableRaster dstOut)
 169:   {
 170: 
 171:     
 172:     
 173:     
 174:     
 175:     
 176: 
 177:     int x0 = src.getMinX();
 178:     int y0 = src.getMinY();
 179:     int width = src.getWidth();
 180:     int height = src.getHeight();
 181:     int x1 = x0 + width;
 182:     int y1 = y0 + height;
 183: 
 184:     Object srcPixel = null;
 185:     Object dstPixel = null;
 186: 
 187:     
 188:     
 189:     float[] srcComponents;
 190:     int srcComponentsLength = srcColorModel.getNumComponents();
 191:     if (! srcColorModel.hasAlpha())
 192:       srcComponentsLength += 1;
 193:     srcComponents = new float[srcComponentsLength];
 194: 
 195:     
 196:     
 197:     float[] dstComponents;
 198:     int dstComponentsLength = dstColorModel.getNumComponents();
 199:     if (! dstColorModel.hasAlpha())
 200:       dstComponentsLength += 1;
 201:     dstComponents = new float[dstComponentsLength];
 202: 
 203:     if (srcComponentsLength != dstComponentsLength)
 204:       throw new AWTError("The color models of the source and destination have"
 205:                          + "incompatible number of color components");
 206: 
 207:     int srcTransferType = srcColorModel.getTransferType();
 208:     int dstTransferType = dstColorModel.getTransferType();
 209: 
 210:     for (int y = y0; y < y1; y++)
 211:       {
 212:         for (int x = x0; x < x1; x++)
 213:           {
 214:             
 215:             srcPixel = src.getDataElements(x, y, (int[]) srcPixel);
 216:             
 217:             dstPixel = dstIn.getDataElements(x, y, dstPixel);
 218:             
 219:             
 220:             srcComponents =
 221:               srcColorModel.getNormalizedComponents(srcPixel, srcComponents, 0);
 222:             if (! srcColorModel.hasAlpha())
 223:               srcComponents[srcComponentsLength - 1] = 1.0F;
 224:             dstComponents =
 225:               dstColorModel.getNormalizedComponents(dstPixel, dstComponents, 0);
 226:             if (! dstColorModel.hasAlpha())
 227:               dstComponents[dstComponentsLength - 1] = 1.0F;
 228: 
 229:             
 230:             float compositeAlpha = composite.getAlpha();
 231:             srcComponents[srcComponentsLength - 1] *= compositeAlpha;
 232:             if (srcColorModel.isAlphaPremultiplied())
 233:               {
 234:                 for (int i = srcComponentsLength - 2; i >= 0; i--)
 235:                   srcComponents[i] *= compositeAlpha;
 236:               }
 237:             else
 238:               {
 239:                 for (int i = srcComponentsLength - 2; i >= 0; i--)
 240:                   srcComponents[i] *= srcComponents[srcComponentsLength - 1];
 241:               }
 242:             if (! dstColorModel.isAlphaPremultiplied())
 243:               {
 244:                 for (int i = dstComponentsLength - 2; i >= 0; i--)
 245:                   dstComponents[i] *= dstComponents[dstComponents.length - 1];
 246:               }
 247: 
 248:             
 249:             
 250:             
 251:             float srcAlpha = srcComponents[srcComponentsLength - 1];
 252:             float dstAlpha = dstComponents[dstComponentsLength - 1];
 253:             switch (composite.getRule())
 254:             {
 255:               case AlphaComposite.DST_ATOP:
 256:                 fs = 1.F - dstAlpha;
 257:                 fd = srcAlpha;
 258:                 break;
 259:               case AlphaComposite.DST_IN:
 260:                 fd = srcAlpha;
 261:                 break;
 262:               case AlphaComposite.DST_OUT:
 263:                 fd = 1.F - srcAlpha;
 264:                 break;
 265:               case AlphaComposite.DST_OVER:
 266:                 fs = 1.F - dstAlpha;
 267:                 break;
 268:               case AlphaComposite.SRC_ATOP:
 269:                 fs = srcAlpha;
 270:                 fd = 1.F - srcAlpha;
 271:                 break;
 272:               case AlphaComposite.SRC_IN:
 273:                 fs = dstAlpha;
 274:                 break;
 275:               case AlphaComposite.SRC_OUT:
 276:                 fs = 1.F - dstAlpha;
 277:                 break;
 278:               case AlphaComposite.SRC_OVER:
 279:                 fd= 1.F - srcAlpha;
 280:                 break;
 281:               case AlphaComposite.XOR:
 282:                 fs = 1.F - dstAlpha;
 283:                 fd= 1.F - srcAlpha;
 284:                 break;
 285:               default:
 286:                 
 287:                 
 288:             }
 289: 
 290:             
 291:             for (int i = 0; i < srcComponentsLength; i++)
 292:               {
 293:                 dstComponents[i] = srcComponents[i] * fs
 294:                                    + dstComponents[i] * fd;
 295:               }
 296: 
 297:             
 298:             
 299:             dstAlpha = dstComponents[dstComponentsLength - 1];
 300:             if (!dstColorModel.isAlphaPremultiplied() && dstAlpha != 0.F)
 301:               {
 302:                 for (int i = 0; i < dstComponentsLength - 1; i++)
 303:                   {
 304:                     dstComponents[i] = dstComponents[i] / dstAlpha;
 305:                   }
 306:               }
 307: 
 308:             
 309:             dstPixel = dstColorModel.getDataElements(dstComponents, 0,
 310:                                                      dstPixel);
 311:             dstOut.setDataElements(x, y, dstPixel);
 312:           } 
 313:       } 
 314:   }
 315: 
 316: }