1 18 package org.apache.batik.ext.awt.image.rendered; 19 20 import java.awt.CompositeContext ; 21 import java.awt.Graphics2D ; 22 import java.awt.Point ; 23 import java.awt.Rectangle ; 24 import java.awt.color.ColorSpace ; 25 import java.awt.image.BufferedImage ; 26 import java.awt.image.ColorModel ; 27 import java.awt.image.DataBuffer ; 28 import java.awt.image.DirectColorModel ; 29 import java.awt.image.Raster ; 30 import java.awt.image.SampleModel ; 31 import java.awt.image.WritableRaster ; 32 import java.util.Iterator ; 33 import java.util.List ; 34 import java.util.Vector ; 35 36 import org.apache.batik.ext.awt.image.CompositeRule; 37 import org.apache.batik.ext.awt.image.GraphicsUtil; 38 import org.apache.batik.ext.awt.image.PadMode; 39 import org.apache.batik.ext.awt.image.SVGComposite; 40 41 48 public class CompositeRed extends AbstractRed { 49 50 CompositeRule rule; 51 CompositeContext [] contexts; 52 53 public CompositeRed(List srcs, CompositeRule rule) { 54 super(); 56 CachableRed src = (CachableRed)srcs.get(0); 57 58 ColorModel cm = fixColorModel (src); 59 60 this.rule = rule; 61 62 SVGComposite comp = new SVGComposite(rule); 63 contexts = new CompositeContext [srcs.size()]; 64 65 int idx = 0; 66 Iterator i = srcs.iterator(); 67 Rectangle myBounds = null; 68 while (i.hasNext()) { 69 CachableRed cr = (CachableRed)i.next(); 70 71 contexts[idx++] = comp.createContext(cr.getColorModel(), cm, null); 72 73 Rectangle newBound = cr.getBounds(); 74 if (myBounds == null) { 75 myBounds = newBound; 76 continue; 77 } 78 79 switch (rule.getRule()) { 80 case CompositeRule.RULE_IN: 81 if (myBounds.intersects(newBound)) 82 myBounds = myBounds.intersection(newBound); 83 else { 84 myBounds.width = 0; 85 myBounds.height = 0; 86 } 87 break; 88 case CompositeRule.RULE_OUT: 89 myBounds = newBound; 91 break; 92 default: 93 myBounds= myBounds.union(newBound); 94 } 95 } 96 97 if (myBounds == null) 98 throw new IllegalArgumentException 99 ("Composite Operation Must have some source!"); 100 101 if (rule.getRule() == CompositeRule.RULE_ARITHMETIC) { 102 Vector vec = new Vector (); 103 i = srcs.iterator(); 104 while (i.hasNext()) { 105 CachableRed cr = (CachableRed)i.next(); 106 Rectangle r = cr.getBounds(); 107 if ((r.x != myBounds.x) || 109 (r.y != myBounds.y) || 110 (r.width != myBounds.width) || 111 (r.height != myBounds.height)) 112 cr = new PadRed(cr, myBounds, PadMode.ZERO_PAD, null); 113 vec.add(cr); 114 } 115 srcs = vec; 116 } 117 118 SampleModel sm = fixSampleModel(src, cm, myBounds); 120 121 124 int defSz = AbstractTiledRed.getDefaultTileSize(); 125 126 int tgX = defSz*(int)Math.floor(myBounds.x/defSz); 128 int tgY = defSz*(int)Math.floor(myBounds.y/defSz); 129 130 init(srcs, myBounds, cm, sm, tgX, tgY, null); 132 } 133 134 public WritableRaster copyData(WritableRaster wr) { 135 genRect(wr); 137 return wr; 138 } 139 140 public Raster getTile(int x, int y) { 141 int tx = tileGridXOff+x*tileWidth; 142 int ty = tileGridYOff+y*tileHeight; 143 Point pt = new Point (tx, ty); 144 WritableRaster wr = Raster.createWritableRaster(sm, pt); 145 genRect(wr); 146 147 return wr; 148 } 149 150 public void emptyRect(WritableRaster wr) { 151 PadRed.ZeroRecter zr = PadRed.ZeroRecter.getZeroRecter(wr); 152 zr.zeroRect(new Rectangle (wr.getMinX(), wr.getMinY(), 153 wr.getWidth(), wr.getHeight())); 154 } 155 156 public void genRect(WritableRaster wr) { 157 Rectangle r = wr.getBounds(); 160 161 int idx = 0; 162 Iterator i = srcs.iterator(); 163 boolean first = true; 164 while (i.hasNext()) { 165 CachableRed cr = (CachableRed)i.next(); 166 if (first) { 167 Rectangle crR = cr.getBounds(); 168 if ((r.x < crR.x) || 169 (r.y < crR.y) || 170 (r.x+r.width > crR.x+crR.width) || 171 (r.y+r.height > crR.y+crR.height)) 172 emptyRect(wr); 174 175 cr.copyData(wr); 177 178 if (cr.getColorModel().isAlphaPremultiplied() == false) 179 GraphicsUtil.coerceData(wr, cr.getColorModel(), true); 180 first = false; 181 } else { 182 Rectangle crR = cr.getBounds(); 183 if (crR.intersects(r)) { 184 Rectangle smR = crR.intersection(r); 185 Raster ras = cr.getData(smR); 186 WritableRaster smWR = wr.createWritableChild 187 (smR.x, smR.y, smR.width, smR.height, 188 smR.x, smR.y, null); 189 190 contexts[idx].compose(ras, smWR, smWR); 191 } 192 } 193 194 idx++; 195 } 196 } 199 200 public void genRect_OVER(WritableRaster wr) { 204 Rectangle r = wr.getBounds(); 207 208 ColorModel cm = getColorModel(); 209 210 BufferedImage bi = new BufferedImage 211 (cm, wr.createWritableTranslatedChild(0,0), 212 cm.isAlphaPremultiplied(), null); 213 214 Graphics2D g2d = GraphicsUtil.createGraphics(bi); 215 g2d.translate(-r.x, -r.y); 216 217 Iterator i = srcs.iterator(); 218 boolean first = true; 219 while (i.hasNext()) { 220 CachableRed cr = (CachableRed)i.next(); 221 if (first) { 222 Rectangle crR = cr.getBounds(); 223 if ((r.x < crR.x) || 224 (r.y < crR.y) || 225 (r.x+r.width > crR.x+crR.width) || 226 (r.y+r.height > crR.y+crR.height)) 227 emptyRect(wr); 229 230 cr.copyData(wr); 232 233 GraphicsUtil.coerceData(wr, cr.getColorModel(), 234 cm.isAlphaPremultiplied()); 235 first = false; 236 } else { 237 GraphicsUtil.drawImage(g2d, cr); 238 } 239 } 240 } 243 244 249 protected static SampleModel fixSampleModel(CachableRed src, 250 ColorModel cm, 251 Rectangle bounds) { 252 int defSz = AbstractTiledRed.getDefaultTileSize(); 253 254 int tgX = defSz*(int)Math.floor(bounds.x/defSz); 256 int tgY = defSz*(int)Math.floor(bounds.y/defSz); 257 258 int tw = (bounds.x+bounds.width)-tgX; 259 int th = (bounds.y+bounds.height)-tgY; 260 261 SampleModel sm = src.getSampleModel(); 262 263 int w = sm.getWidth(); 264 if (w < defSz) w = defSz; 265 if (w > tw) w = tw; 266 267 int h = sm.getHeight(); 268 if (h < defSz) h = defSz; 269 if (h > th) h = th; 270 271 if ((w <= 0) || (h <= 0)) { 272 w = 1; 273 h = 1; 274 } 275 276 280 return cm.createCompatibleSampleModel(w, h); 281 } 282 283 protected static ColorModel fixColorModel(CachableRed src) { 284 ColorModel cm = src.getColorModel(); 285 286 if (cm.hasAlpha()) { 287 if (!cm.isAlphaPremultiplied()) 288 cm = GraphicsUtil.coerceColorModel(cm, true); 289 return cm; 290 } 291 292 int b = src.getSampleModel().getNumBands()+1; 293 if (b > 4) 294 throw new IllegalArgumentException 295 ("CompositeRed can only handle up to three band images"); 296 297 int [] masks = new int[4]; 298 for (int i=0; i < b-1; i++) 299 masks[i] = 0xFF0000 >> (8*i); 300 masks[3] = 0xFF << (8*(b-1)); 301 ColorSpace cs = cm.getColorSpace(); 302 303 return new DirectColorModel (cs, 8*b, masks[0], masks[1], 304 masks[2], masks[3], 305 true, DataBuffer.TYPE_INT); 306 } 307 } 308 | Popular Tags |