001/* 002Copyright 2006 Jerry Huxtable 003 004Licensed under the Apache License, Version 2.0 (the "License"); 005you may not use this file except in compliance with the License. 006You may obtain a copy of the License at 007 008 http://www.apache.org/licenses/LICENSE-2.0 009 010Unless required by applicable law or agreed to in writing, software 011distributed under the License is distributed on an "AS IS" BASIS, 012WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013See the License for the specific language governing permissions and 014limitations under the License. 015*/ 016 017package com.jhlabs.composite; 018 019import java.awt.*; 020import java.awt.image.*; 021import java.awt.color.*; 022 023/** 024 * A special Composite used for drawing "marching ants". It draws the ants at the 127 contour of the alpha channel of the source. 025 * This can only be used on TYPE_INT_RGBA images. 026 */ 027public final class ContourComposite implements Composite { 028 029 private int offset; 030 031 public ContourComposite( int offset ) { 032 this.offset = offset; 033 } 034 035 public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints) { 036 return new ContourCompositeContext( offset, srcColorModel, dstColorModel ); 037 } 038 039 public int hashCode() { 040 return 0; 041 } 042 043 public boolean equals(Object o) { 044 if (!(o instanceof ContourComposite)) 045 return false; 046 return true; 047 } 048 049} 050 051class ContourCompositeContext implements CompositeContext { 052 053 private int offset; 054 055 public ContourCompositeContext( int offset, ColorModel srcColorModel, ColorModel dstColorModel ) { 056 this.offset = offset; 057 } 058 059 public void dispose() { 060 } 061 062 public void compose(Raster src, Raster dstIn, WritableRaster dstOut) { 063 int x = src.getMinX(); 064 int y = src.getMinY(); 065 int w = src.getWidth(); 066 int h = src.getHeight(); 067 068 int[] srcPix = null; 069 int[] srcPix2 = null; 070 int[] dstInPix = null; 071 int[] dstOutPix = new int[w*4]; 072 073 for ( int i = 0; i < h; i++ ) { 074 srcPix = src.getPixels(x, y, w, 1, srcPix); 075 dstInPix = dstIn.getPixels(x, y, w, 1, dstInPix); 076 077 int lastAlpha = 0; 078 int k = 0; 079 for ( int j = 0; j < w; j++ ) { 080 int alpha = srcPix[k+3]; 081 int alphaAbove = i != 0 ? srcPix2[k+3] : alpha; 082 083 if ( i != 0 && j != 0 && ((alpha ^ lastAlpha) & 0x80) != 0 || ((alpha ^ alphaAbove) & 0x80) != 0 ) { 084 if ((offset+i+j)%10 > 4) { 085 dstOutPix[k] = 0x00; 086 dstOutPix[k+1] = 0x00; 087 dstOutPix[k+2] = 0x00; 088 } else { 089 dstOutPix[k] = 0xff; 090 dstOutPix[k+1] = 0xff; 091 dstOutPix[k+2] = 0x7f; 092 } 093 dstOutPix[k+3] = 0xff; 094 } else { 095 dstOutPix[k] = dstInPix[k]; 096 dstOutPix[k+1] = dstInPix[k+1]; 097 dstOutPix[k+2] = dstInPix[k+2]; 098// if ( dstOut == dstIn ) 099 dstOutPix[k] = 0xff; 100 dstOutPix[k+1] = 0; 101 dstOutPix[k+2] = 0; 102 dstOutPix[k+3] = 0; 103// else 104// dstOutPix[k+3] = dstInPix[k+3]; 105 } 106 107 lastAlpha = alpha; 108 k += 4; 109 } 110 111 dstOut.setPixels(x, y, w, 1, dstOutPix); 112 113 int[] t = srcPix; 114 srcPix = srcPix2; 115 srcPix2 = t; 116 y++; 117 } 118 } 119 120}