1 18 package org.apache.batik.ext.awt.image.rendered; 19 20 import java.awt.AlphaComposite ; 21 import java.awt.Color ; 22 import java.awt.Graphics2D ; 23 import java.awt.Point ; 24 import java.awt.Rectangle ; 25 import java.awt.RenderingHints ; 26 import java.awt.geom.AffineTransform ; 27 import java.awt.image.BufferedImage ; 28 import java.awt.image.ColorModel ; 29 import java.awt.image.DataBufferInt ; 30 import java.awt.image.Raster ; 31 import java.awt.image.RenderedImage ; 32 import java.awt.image.SampleModel ; 33 import java.awt.image.SinglePixelPackedSampleModel ; 34 import java.awt.image.WritableRaster ; 35 36 import org.apache.batik.ext.awt.image.GraphicsUtil; 37 import org.apache.batik.util.HaltingThread; 38 39 46 public class TileRed extends AbstractRed implements TileGenerator { 47 static final AffineTransform IDENTITY = new AffineTransform (); 48 49 52 Rectangle tiledRegion; 53 54 int xStep; 55 int yStep; 56 57 TileStore tiles; 58 59 private RenderingHints hints; 60 61 final boolean is_INT_PACK; 62 final boolean alphaPremult; 63 64 67 RenderedImage tile = null; 68 WritableRaster raster = null; 69 70 71 public TileRed(RenderedImage tile, 72 Rectangle tiledRegion) { 73 this(tile, tiledRegion, tile.getWidth(), tile.getHeight(), null); 74 } 75 76 public TileRed(RenderedImage tile, 77 Rectangle tiledRegion, 78 RenderingHints hints) { 79 this(tile, tiledRegion, tile.getWidth(), tile.getHeight(), hints); 80 } 81 82 public TileRed(RenderedImage tile, 83 Rectangle tiledRegion, 84 int xStep, int yStep) { 85 this(tile, tiledRegion, xStep, yStep, null); 86 } 87 88 public TileRed(RenderedImage tile, 89 Rectangle tiledRegion, 90 int xStep, int yStep, 91 RenderingHints hints) { 92 if(tiledRegion == null){ 93 throw new IllegalArgumentException (); 94 } 95 96 if(tile == null){ 97 throw new IllegalArgumentException (); 98 } 99 100 this.tiledRegion = tiledRegion; 102 this.xStep = xStep; 103 this.yStep = yStep; 104 this.hints = hints; 105 this.alphaPremult = false; 106 107 SampleModel sm = fixSampleModel(tile, xStep, yStep, 108 tiledRegion.width, 109 tiledRegion.height); 110 ColorModel cm = fixColorModel(tile, alphaPremult); 111 112 double smSz = AbstractTiledRed.getDefaultTileSize(); 113 smSz = smSz*smSz; 114 115 double stepSz = (xStep*(double)yStep); 116 if (16.1*smSz > stepSz) { 119 int xSz = xStep; 120 int ySz = yStep; 121 122 if (4*stepSz <= smSz) { 125 int mult = (int)Math.ceil(Math.sqrt(smSz/stepSz)); 126 xSz *= mult; 127 ySz *= mult; 128 } 129 sm = sm.createCompatibleSampleModel(xSz, ySz); 131 raster = Raster.createWritableRaster 132 (sm, new Point (tile.getMinX(), tile.getMinY())); 133 } 134 135 is_INT_PACK = GraphicsUtil.is_INT_PACK_Data(sm, false); 136 138 init((CachableRed)null, tiledRegion, cm, sm, 145 tile.getMinX(), tile.getMinY(), null); 146 147 if (raster != null) { 148 WritableRaster fromRaster = raster.createWritableChild 149 (tile.getMinX(), tile.getMinY(), 150 xStep, yStep, tile.getMinX(), tile.getMinY(), null); 151 152 fillRasterFrom(fromRaster, tile); 154 fillOutRaster(raster); 155 } 156 else { 157 this.tile = new TileCacheRed(GraphicsUtil.wrap(tile)); 158 } 159 } 160 161 public WritableRaster copyData(WritableRaster wr) { 162 int xOff = ((int)Math.floor(wr.getMinX()/xStep))*xStep; 163 int yOff = ((int)Math.floor(wr.getMinY()/yStep))*yStep; 164 int x0 = wr.getMinX()-xOff; 165 int y0 = wr.getMinY()-yOff; 166 int tx0 = getXTile(x0); 167 int ty0 = getYTile(y0); 168 int tx1 = getXTile(x0+wr.getWidth() -1); 169 int ty1 = getYTile(y0+wr.getHeight()-1); 170 171 for (int y=ty0; y<=ty1; y++) 172 for (int x=tx0; x<=tx1; x++) { 173 Raster r = getTile(x, y); 174 r = r.createChild(r.getMinX(), r.getMinY(), 175 r.getWidth(), r.getHeight(), 176 r.getMinX()+xOff, r.getMinY()+yOff, null); 177 if (is_INT_PACK) 178 GraphicsUtil.copyData_INT_PACK(r, wr); 179 else 180 GraphicsUtil.copyData_FALLBACK(r, wr); 181 } 182 return wr; 183 } 184 185 186 public Raster getTile(int x, int y) { 187 188 if (raster!=null) { 189 int tx = tileGridXOff+x*tileWidth; 192 int ty = tileGridYOff+y*tileHeight; 193 return raster.createTranslatedChild(tx, ty); 194 } 195 196 return genTile(x,y); 198 } 199 200 public Raster genTile(int x, int y) { 201 int tx = tileGridXOff+x*tileWidth; 203 int ty = tileGridYOff+y*tileHeight; 204 205 if (raster!=null) { 206 return raster.createTranslatedChild(tx, ty); 209 } 210 211 Point pt = new Point (tx, ty); 212 WritableRaster wr = Raster.createWritableRaster(sm, pt); 213 fillRasterFrom(wr, tile); 214 return wr; 215 } 216 217 public WritableRaster fillRasterFrom(WritableRaster wr, RenderedImage src){ 218 221 ColorModel cm = getColorModel(); 222 BufferedImage bi 223 = new BufferedImage (cm, 224 wr.createWritableTranslatedChild(0, 0), 225 cm.isAlphaPremultiplied(), null); 226 227 Graphics2D g = GraphicsUtil.createGraphics(bi, hints); 228 229 int minX = wr.getMinX(); 230 int minY = wr.getMinY(); 231 int maxX = wr.getWidth(); 232 int maxY = wr.getHeight(); 233 234 235 g.setComposite(AlphaComposite.Clear); 236 g.setColor(new Color (0, 0, 0, 0)); 237 g.fillRect(0, 0, maxX, maxY); 238 g.setComposite(AlphaComposite.SrcOver); 239 240 g.translate(-minX, -minY); 241 242 int x1 = src.getMinX()+src.getWidth()-1; 246 int y1 = src.getMinY()+src.getHeight()-1; 247 248 int tileTx = (int)Math.ceil(((minX-x1)/xStep))*xStep; 249 int tileTy = (int)Math.ceil(((minY-y1)/yStep))*yStep; 250 251 g.translate(tileTx, tileTy); 252 253 int curX = tileTx - wr.getMinX() + src.getMinX(); 254 int curY = tileTy - wr.getMinY() + src.getMinY(); 255 256 minX = curX; 263 while(curY < maxY) { 264 if (HaltingThread.hasBeenHalted()) 265 return wr; 266 267 while (curX < maxX) { 268 GraphicsUtil.drawImage(g, src); 274 curX += xStep; 275 g.translate(xStep, 0); 276 } 277 curY += yStep; 278 g.translate(minX-curX, yStep); 279 curX = minX; 280 } 281 282 287 GraphicsUtil.coerceData(wr, src.getColorModel(), alphaPremult); 288 return wr; 289 } 290 291 protected void fillOutRaster(WritableRaster wr) { 292 if (is_INT_PACK) 293 fillOutRaster_INT_PACK(wr); 294 else 295 fillOutRaster_FALLBACK(wr); 296 297 } 298 299 protected void fillOutRaster_INT_PACK(WritableRaster wr) { 300 int x0 = wr.getMinX(); 302 int y0 = wr.getMinY(); 303 int width = wr.getWidth(); 304 int height = wr.getHeight(); 305 306 SinglePixelPackedSampleModel sppsm; 307 sppsm = (SinglePixelPackedSampleModel )wr.getSampleModel(); 308 309 final int scanStride = sppsm.getScanlineStride(); 310 DataBufferInt db = (DataBufferInt )wr.getDataBuffer(); 311 final int [] pixels = db.getBankData()[0]; 312 final int base = 313 (db.getOffset() + 314 sppsm.getOffset(x0-wr.getSampleModelTranslateX(), 315 y0-wr.getSampleModelTranslateY())); 316 int step = xStep; 317 for (int x=xStep; x<width; x+=step, step*=2) { 318 int w = step; 319 if (x+w > width) w = width-x; 320 if (w >= 128) { 321 int srcSP = base; 322 int dstSP = base+x; 323 for(int y=0; y<yStep; y++) { 324 System.arraycopy(pixels, srcSP, pixels, dstSP, w); 325 srcSP += scanStride; 326 dstSP += scanStride; 327 } 328 } else { 329 int srcSP = base; 330 int dstSP = base+x; 331 for(int y=0; y<yStep; y++) { 332 int end = srcSP; 333 srcSP += w-1; 334 dstSP += w-1; 335 while(srcSP>=end) 336 pixels[dstSP--] = pixels[srcSP--]; 337 srcSP+=scanStride+1; 338 dstSP+=scanStride+1; 339 } 340 } 341 } 342 343 step = yStep; 344 for (int y=yStep; y<height; y+=step, step*=2) { 345 int h = step; 346 if (y+h > height) h = height-y; 347 int dstSP = base+y*scanStride; 348 System.arraycopy(pixels, base, pixels, dstSP, h*scanStride); 349 } 350 } 351 352 protected void fillOutRaster_FALLBACK(WritableRaster wr) { 353 int width = wr.getWidth(); 355 int height = wr.getHeight(); 356 357 Object data = null; 358 359 int step = xStep; 360 for (int x=xStep; x<width; x+=step, step*=4) { 361 int w = step; 362 if (x+w > width) w = width-x; 363 data = wr.getDataElements(0, 0, w, yStep, data); 364 wr.setDataElements(x, 0, w, yStep, data); 365 x+=w; 366 367 if (x >= width) break; 368 if (x+w > width) w = width-x; 369 wr.setDataElements(x, 0, w, yStep, data); 370 x+=w; 371 372 if (x >= width) break; 373 if (x+w > width) w = width-x; 374 wr.setDataElements(x, 0, w, yStep, data); 375 } 376 377 step = yStep; 378 for (int y=yStep; y<height; y+=step, step*=4) { 379 int h = step; 380 if (y+h > height) h = height-y; 381 data = wr.getDataElements(0, 0, width, h, data); 382 wr.setDataElements(0, y, width, h, data); 383 y+=h; 384 385 if (h >= height) break; 386 if (y+h > height) h = height-y; 387 wr.setDataElements(0, y, width, h, data); 388 y+=h; 389 390 if (h >= height) break; 391 if (y+h > height) h = height-y; 392 wr.setDataElements(0, y, width, h, data); 393 y+=h; 394 } 395 } 396 397 protected static ColorModel fixColorModel(RenderedImage src, 398 boolean alphaPremult) { 399 return GraphicsUtil.coerceColorModel(src.getColorModel(), 400 alphaPremult); 401 } 402 403 408 protected static SampleModel fixSampleModel(RenderedImage src, 409 int stepX, int stepY, 410 int width, int height) { 411 int defSz = AbstractTiledRed.getDefaultTileSize(); 412 SampleModel sm = src.getSampleModel(); 413 int w = sm.getWidth(); 414 if (w < defSz) w = defSz; 415 if (w > stepX) w = stepX; 416 int h = sm.getHeight(); 418 if (h < defSz) h = defSz; 419 if (h > stepY) h = stepY; 420 return sm.createCompatibleSampleModel(w, h); 422 } 423 } 424 | Popular Tags |