1 18 package org.apache.batik.ext.awt.image.rendered; 19 20 import java.awt.Point ; 21 import java.awt.Rectangle ; 22 import java.awt.RenderingHints ; 23 import java.awt.Transparency ; 24 import java.awt.color.ColorSpace ; 25 import java.awt.geom.AffineTransform ; 26 import java.awt.geom.NoninvertibleTransformException ; 27 import java.awt.geom.Point2D ; 28 import java.awt.image.AffineTransformOp ; 29 import java.awt.image.BufferedImage ; 30 import java.awt.image.ColorModel ; 31 import java.awt.image.ComponentColorModel ; 32 import java.awt.image.DataBuffer ; 33 import java.awt.image.DirectColorModel ; 34 import java.awt.image.Raster ; 35 import java.awt.image.SampleModel ; 36 import java.awt.image.WritableRaster ; 37 38 import org.apache.batik.ext.awt.image.GraphicsUtil; 39 40 47 public class AffineRed extends AbstractRed { 48 49 RenderingHints hints; 50 AffineTransform src2me; 51 AffineTransform me2src; 52 53 public AffineTransform getTransform() { 54 return (AffineTransform )src2me.clone(); 55 } 56 57 public CachableRed getSource() { 58 return (CachableRed)getSources().get(0); 59 } 60 61 public AffineRed(CachableRed src, 62 AffineTransform src2me, 63 RenderingHints hints) { 64 super(); 66 this.src2me = src2me; 67 this.hints = hints; 68 69 try { 70 me2src = src2me.createInverse(); 71 } catch (NoninvertibleTransformException nite) { 72 me2src = null; 73 } 74 75 Rectangle srcBounds = src.getBounds(); 78 Rectangle myBounds; 80 myBounds = src2me.createTransformedShape(srcBounds).getBounds(); 81 82 ColorModel cm = fixColorModel(src); 87 88 SampleModel sm = fixSampleModel(src, cm, myBounds); 90 91 Point2D pt = new Point2D.Float (src.getTileGridXOffset(), 92 src.getTileGridYOffset()); 93 pt = src2me.transform(pt, null); 94 95 init(src, myBounds, cm, sm, 97 (int)pt.getX(), (int)pt.getY(), null); 98 } 99 100 public WritableRaster copyData(WritableRaster wr) { 101 102 104 PadRed.ZeroRecter zr = PadRed.ZeroRecter.getZeroRecter(wr); 106 zr.zeroRect(new Rectangle (wr.getMinX(), wr.getMinY(), 107 wr.getWidth(), wr.getHeight())); 108 genRect(wr); 109 return wr; 110 } 111 112 public Raster getTile(int x, int y) { 113 if (me2src == null) 114 return null; 115 116 int tx = tileGridXOff+x*tileWidth; 117 int ty = tileGridYOff+y*tileHeight; 118 Point pt = new Point (tx, ty); 119 WritableRaster wr = Raster.createWritableRaster(sm, pt); 120 genRect(wr); 121 122 return wr; 123 } 124 125 public void genRect(WritableRaster wr) { 126 if (me2src == null) 127 return; 128 129 Rectangle srcR 130 = me2src.createTransformedShape(wr.getBounds()).getBounds(); 131 132 135 srcR.setBounds(srcR.x-1, srcR.y-1, srcR.width+2, srcR.height+2); 137 138 CachableRed src = (CachableRed)getSources().get(0); 140 141 143 if (srcR.intersects(src.getBounds()) == false) 144 return; 145 Raster srcRas = src.getData(srcR.intersection(src.getBounds())); 146 147 if (srcRas == null) 148 return; 149 150 AffineTransform aff = (AffineTransform )src2me.clone(); 153 154 aff.concatenate(AffineTransform.getTranslateInstance 157 (srcRas.getMinX(), srcRas.getMinY())); 158 159 Point2D srcPt = new Point2D.Float (wr.getMinX(), wr.getMinY()); 160 srcPt = me2src.transform(srcPt, null); 161 162 Point2D destPt = new Point2D.Double (srcPt.getX()-srcRas.getMinX(), 163 srcPt.getY()-srcRas.getMinY()); 164 165 destPt = aff.transform(destPt, null); 166 167 168 aff.preConcatenate(AffineTransform.getTranslateInstance 171 (-destPt.getX(), -destPt.getY())); 172 173 AffineTransformOp op = new AffineTransformOp (aff, hints); 174 175 BufferedImage srcBI, myBI; 176 ColorModel srcCM = src.getColorModel(); 177 ColorModel myCM = getColorModel(); 178 179 WritableRaster srcWR = (WritableRaster )srcRas; 180 srcCM = GraphicsUtil.coerceData(srcWR, srcCM, true); 185 srcBI = new BufferedImage (srcCM, 186 srcWR.createWritableTranslatedChild(0,0), 187 srcCM.isAlphaPremultiplied(), null); 188 189 myBI = new BufferedImage (myCM,wr.createWritableTranslatedChild(0,0), 190 myCM.isAlphaPremultiplied(), null); 191 192 op.filter(srcBI, myBI); 193 194 } 200 201 203 protected static ColorModel fixColorModel(CachableRed src) { 204 ColorModel cm = src.getColorModel(); 205 206 if (cm.hasAlpha()) { 207 if (!cm.isAlphaPremultiplied()) 208 cm = GraphicsUtil.coerceColorModel(cm, true); 209 return cm; 210 } 211 212 ColorSpace cs = cm.getColorSpace(); 213 214 int b = src.getSampleModel().getNumBands()+1; 215 if (b == 4) { 216 int [] masks = new int[4]; 217 for (int i=0; i < b-1; i++) 218 masks[i] = 0xFF0000 >> (8*i); 219 masks[3] = 0xFF << (8*(b-1)); 220 221 return new DirectColorModel (cs, 8*b, masks[0], masks[1], 222 masks[2], masks[3], 223 true, DataBuffer.TYPE_INT); 224 } 225 226 int [] bits = new int[b]; 227 for (int i=0; i<b; i++) 228 bits[i] = 8; 229 return new ComponentColorModel (cs, bits, true, true, 230 Transparency.TRANSLUCENT, 231 DataBuffer.TYPE_INT); 232 233 } 234 235 240 protected SampleModel fixSampleModel(CachableRed src, 241 ColorModel cm, 242 Rectangle bounds) { 243 SampleModel sm = src.getSampleModel(); 244 int defSz = AbstractTiledRed.getDefaultTileSize(); 245 246 int w = sm.getWidth(); 247 if (w < defSz) w = defSz; 248 if (w > bounds.width) w = bounds.width; 249 int h = sm.getHeight(); 250 if (h < defSz) h = defSz; 251 if (h > bounds.height) h = bounds.height; 252 253 if ((w <= 0) || (h <= 0)) { 254 w = 1; 255 h = 1; 256 } 257 258 return cm.createCompatibleSampleModel(w, h); 259 } 260 } 261 | Popular Tags |