/*****************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved. *
* ------------------------------------------------------------------------- *
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in *
* the LICENSE file. *
*****************************************************************************/
package org.apache.batik.gvt;
import java.awt.PaintContext;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.awt.image.WritableRaster;
import java.awt.image.renderable.RenderContext;
import org.apache.batik.ext.awt.image.GraphicsUtil;
import org.apache.batik.ext.awt.image.renderable.Filter;
import org.apache.batik.ext.awt.image.renderable.TileRable;
import org.apache.batik.ext.awt.image.renderable.TileRable8Bit;
import org.apache.batik.ext.awt.image.rendered.TileCacheRed;
/**
* <tt>PaintContext</tt> for the <tt>ConcretePatterPaint</tt>
* paint implementation.
*
* @author <a href="vincent.hardy@eng.sun.com">Vincent Hardy</a>
* @version $Id: PatternPaintContext.java,v 1.11 2003/04/11 13:58:30 vhardy Exp $
*/
public class PatternPaintContext implements PaintContext {
/**
* ColorModel for the Rasters created by this Paint
*/
private ColorModel rasterCM;
/**
* Working Raster
*/
private WritableRaster raster;
/**
* Tile
*/
private RenderedImage tiled;
protected AffineTransform usr2dev;
public AffineTransform getUsr2Dev() { return usr2dev; }
private static Rectangle EVERYTHING =
new Rectangle(Integer.MIN_VALUE/4, Integer.MIN_VALUE/4,
Integer.MAX_VALUE/2, Integer.MAX_VALUE/2);
/**
* @param destCM ColorModel that receives the paint data
* @param usr2dev user space to device space transform
* @param hints RenderingHints
* @param patternRegion region tiled by this paint. In user space.
* @param overflow controls whether the pattern region clips the
* pattern tile
*/
public PatternPaintContext(ColorModel destCM,
AffineTransform usr2dev,
RenderingHints hints,
Filter tile,
Rectangle2D patternRegion,
boolean overflow) {
if(usr2dev == null){
throw new IllegalArgumentException();
}
if(hints == null){
hints = new RenderingHints(null);
}
if(tile == null){
throw new IllegalArgumentException();
}
this.usr2dev = usr2dev;
// System.out.println("PatB: " + patternRegion);
// System.out.println("Tile: " + tile);
TileRable tileRable = new TileRable8Bit(tile,
EVERYTHING,
patternRegion,
overflow);
ColorSpace destCS = destCM.getColorSpace();
if (destCS == ColorSpace.getInstance(ColorSpace.CS_sRGB))
tileRable.setColorSpaceLinear(false);
else if (destCS == ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB))
tileRable.setColorSpaceLinear(true);
RenderContext rc = new RenderContext(usr2dev, EVERYTHING, hints);
tiled = tileRable.createRendering(rc);
// System.out.println("tileRed: " + tiled);
// org.apache.batik.test.gvt.ImageDisplay.showImage("Tiled: ", tiled);
//System.out.println("Created rendering");
if(tiled != null) {
Rectangle2D devRgn = usr2dev.createTransformedShape
(patternRegion).getBounds();
if ((devRgn.getWidth() > 128) ||
(devRgn.getHeight() > 128))
tiled = new TileCacheRed(GraphicsUtil.wrap(tiled), 256, 64);
} else {
//System.out.println("Tile was null");
rasterCM = ColorModel.getRGBdefault();
WritableRaster wr;
wr = rasterCM.createCompatibleWritableRaster(32, 32);
tiled = GraphicsUtil.wrap
(new BufferedImage(rasterCM, wr, false, null));
return;
}
rasterCM = tiled.getColorModel();
if (rasterCM.hasAlpha()) {
if (destCM.hasAlpha())
rasterCM = GraphicsUtil.coerceColorModel
(rasterCM, destCM.isAlphaPremultiplied());
else
rasterCM = GraphicsUtil.coerceColorModel(rasterCM, false);
}
}
public void dispose(){
raster = null;
}
public ColorModel getColorModel(){
return rasterCM;
}
public Raster getRaster(int x, int y, int width, int height){
// System.out.println("GetRaster: [" + x + ", " + y + ", "
// + width + ", " + height + "]");
if ((raster == null) ||
(raster.getWidth() < width) ||
(raster.getHeight() < height)) {
raster = rasterCM.createCompatibleWritableRaster(width, height);
}
WritableRaster wr
= raster.createWritableChild(0, 0, width, height, x, y, null);
tiled.copyData(wr);
GraphicsUtil.coerceData(wr, tiled.getColorModel(),
rasterCM.isAlphaPremultiplied());
// On Mac OS X it always wants the raster at 0,0 if the
// requested width and height matches raster we can just
// return it. Otherwise we create a translated child that
// lives at 0,0.
if ((raster.getWidth() == width) &&
(raster.getHeight() == height))
return raster;
return wr.createTranslatedChild(0,0);
}
}