in batik-awt-util/src/main/java/org/apache/batik/ext/awt/image/renderable/TileRable8Bit.java [356:704]
public RenderedImage createTile(RenderContext rc){
AffineTransform usr2dev = rc.getTransform();
// Hints
RenderingHints rcHints = rc.getRenderingHints();
RenderingHints hints = new RenderingHints(null);
if(rcHints != null){
hints.add(rcHints);
}
// The region actually tiles is the intersection
// of the tiledRegion and the area of interest
Rectangle2D tiledRect = getBounds2D();
Shape aoiShape = rc.getAreaOfInterest();
Rectangle2D aoiRect = aoiShape.getBounds2D();
if ( ! tiledRect.intersects(aoiRect) )
return null;
Rectangle2D.intersect(tiledRect, aoiRect, tiledRect);
// Get the tile rectangle in user space
Rectangle2D tileRect = (Rectangle2D)tileRegion.clone();
// System.out.println("tileRect : " + tileRect);
// System.out.println("tiledRect: " + tiledRect);
if ((tileRect.getWidth() <= 0)
|| (tileRect.getHeight() <= 0)
|| (tiledRect.getWidth() <= 0)
|| (tiledRect.getHeight() <= 0))
return null;
//
// (tiledX, tiledY)
// <------- min(tileWidth, tiledWidth) ----------->
// ^ +------+-------------------------------------+
// | + A' + B' +
// | +------+-------------------------------------+
// min(tileHeight, | + + +
// tiledHeight) | + + +
// | + C' + D' +
// | + + +
// ^ +------+-------------------------------------+
//
// Maps to, in the tile:
//
// (tileX, tileY)
//
// <----------- tileWidth --------------->
// ^ +-----------------------------+------+-------+
// | + + + |
// tiledHeight | + + + |
// | + D + + C |
// | + + + |
// | +-----------------------------+------+-------|
// | + | | |
// | + | | |
// | +-----------------------------+------+-------+
// | | B + + A |
// ^ +-----------------------------+------+-------+
// w = min(tileWidth, tiledWidth)
// h = min(tileHeight, tiledHeight)
// dx = tileWidth - (tiledX - tileX)%tileWidth;
// dy = tileHeight - (tiledY - tileY)%tileHeight;
//
// A = (tileX + tileWidth - dx, tileY + tileHeight - dy, dx, dy)
// B = (tileX, tileY + tileHeight - dy, w - dx, dy)
// C = (tileX + tileWidth - dx, tileY, dx, h - dy)
// D = (tileX, tileY, w - dx, h - dy)
double tileX = tileRect.getX();
double tileY = tileRect.getY();
double tileWidth = tileRect.getWidth();
double tileHeight = tileRect.getHeight();
double tiledX = tiledRect.getX();
double tiledY = tiledRect.getY();
double tiledWidth = tiledRect.getWidth();
double tiledHeight = tiledRect.getHeight();
double w = Math.min(tileWidth, tiledWidth);
double h = Math.min(tileHeight, tiledHeight);
double dx = (tiledX - tileX)%tileWidth;
double dy = (tiledY - tileY)%tileHeight;
if(dx > 0){
dx = tileWidth - dx;
}
else{
dx *= -1;
}
if(dy > 0){
dy = tileHeight - dy;
}
else{
dy *= -1;
}
//
// Adjust dx and dy so that they fall on a pixel boundary
//
double scaleX = usr2dev.getScaleX();
double scaleY = usr2dev.getScaleY();
double tdx = Math.floor(scaleX*dx);
double tdy = Math.floor(scaleY*dy);
dx = tdx/scaleX;
dy = tdy/scaleY;
// System.out.println("dx / dy / w / h : " + dx + " / " + dy + " / " + w + " / " + h);
Rectangle2D.Double A = new Rectangle2D.Double
(tileX + tileWidth - dx, tileY + tileHeight - dy, dx, dy);
Rectangle2D.Double B = new Rectangle2D.Double
(tileX, tileY + tileHeight - dy, w - dx, dy);
Rectangle2D.Double C = new Rectangle2D.Double
(tileX + tileWidth - dx, tileY, dx, h - dy);
Rectangle2D.Double D = new Rectangle2D.Double
(tileX, tileY, w - dx, h - dy);
Rectangle2D realTileRect
= new Rectangle2D.Double(tiledRect.getX(),
tiledRect.getY(),
w, h);
// System.out.println("A rect : " + A);
// System.out.println("B rect : " + B);
// System.out.println("C rect : " + C);
// System.out.println("D rect : " + D);
// System.out.println("realTileR : " + realTileRect);
// A, B, C and D are the four user space are that make the
// tile that will be used. We create a rendering for each of
// these areas that i s not empty (i.e., with either width or
// height equal to zero)
RenderedImage ARed = null, BRed = null, CRed = null, DRed = null;
Filter source = getSource();
if (A.getWidth() > 0 && A.getHeight() > 0){
// System.out.println("Rendering A");
Rectangle devA = usr2dev.createTransformedShape(A).getBounds();
if(devA.width > 0 && devA.height > 0){
AffineTransform ATxf = new AffineTransform(usr2dev);
ATxf.translate(-A.x + tiledX,
-A.y + tiledY);
Shape aoi = A;
if(overflow){
aoi = new Rectangle2D.Double(A.x,
A.y,
tiledWidth,
tiledHeight);
}
hints.put(RenderingHintsKeyExt.KEY_AREA_OF_INTEREST,
aoi);
RenderContext arc
= new RenderContext(ATxf, aoi, hints);
ARed = source.createRendering(arc);
//System.out.println("ARed : " + ARed.getMinX() + " / " +
// ARed.getMinY() + " / " +
// ARed.getWidth() + " / " +
// ARed.getHeight());
}
}
if(B.getWidth() > 0 && B.getHeight() > 0){
// System.out.println("Rendering B");
Rectangle devB = usr2dev.createTransformedShape(B).getBounds();
if(devB.width > 0 && devB.height > 0){
AffineTransform BTxf = new AffineTransform(usr2dev);
BTxf.translate(-B.x + (tiledX + dx),
-B.y + tiledY);
Shape aoi = B;
if(overflow){
aoi = new Rectangle2D.Double(B.x - tiledWidth + w - dx,
B.y,
tiledWidth,
tiledHeight);
}
hints.put(RenderingHintsKeyExt.KEY_AREA_OF_INTEREST,
aoi);
RenderContext brc
= new RenderContext(BTxf, aoi, hints);
BRed = source.createRendering(brc);
// System.out.println("BRed : " + BRed.getMinX() + " / " + BRed.getMinY() + " / " + BRed.getWidth() + " / " + BRed.getHeight());
}
}
if(C.getWidth() > 0 && C.getHeight() > 0){
// System.out.println("Rendering C");
Rectangle devC = usr2dev.createTransformedShape(C).getBounds();
if(devC.width > 0 && devC.height > 0){
AffineTransform CTxf = new AffineTransform(usr2dev);
CTxf.translate(-C.x + tiledX,
-C.y + (tiledY + dy));
Shape aoi = C;
if(overflow){
aoi = new Rectangle2D.Double(C.x,
C.y - tileHeight + h - dy,
tiledWidth,
tiledHeight);
}
hints.put(RenderingHintsKeyExt.KEY_AREA_OF_INTEREST,
aoi);
RenderContext crc
= new RenderContext(CTxf, aoi, hints);
CRed = source.createRendering(crc);
// System.out.println("CRed : " + CRed.getMinX() + " / " + CRed.getMinY() + " / " + CRed.getWidth() + " / " + CRed.getHeight());
}
}
if(D.getWidth() > 0 && D.getHeight() > 0){
// System.out.println("Rendering D");
Rectangle devD = usr2dev.createTransformedShape(D).getBounds();
if(devD.width > 0 && devD.height > 0){
AffineTransform DTxf = new AffineTransform(usr2dev);
DTxf.translate(-D.x + (tiledX + dx),
-D.y + (tiledY + dy));
Shape aoi = D;
if(overflow){
aoi = new Rectangle2D.Double(D.x - tileWidth + w - dx,
D.y - tileHeight + h - dy,
tiledWidth,
tiledHeight);
}
hints.put(RenderingHintsKeyExt.KEY_AREA_OF_INTEREST,
aoi);
RenderContext drc
= new RenderContext(DTxf, aoi, hints);
DRed = source.createRendering(drc);
// System.out.println("DRed : " + DRed.getMinX() + " / " + DRed.getMinY() + " / " + DRed.getWidth() + " / " + DRed.getHeight());
}
}
//
// Now, combine ARed, BRed, CRed and DRed into a single
// RenderedImage that will be tiled
//
final Rectangle realTileRectDev
= usr2dev.createTransformedShape(realTileRect).getBounds();
if(realTileRectDev.width == 0 || realTileRectDev.height == 0){
return null;
}
BufferedImage realTileBI
= new BufferedImage(realTileRectDev.width,
realTileRectDev.height,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = GraphicsUtil.createGraphics(realTileBI,
rc.getRenderingHints());
// g.setPaint(new java.awt.Color(0, 255, 0, 64));
// g.fillRect(0, 0, realTileBI.getWidth(), realTileBI.getHeight());
g.translate(-realTileRectDev.x,
-realTileRectDev.y);
// System.out.println("realTileRectDev " + realTileRectDev);
AffineTransform redTxf = new AffineTransform();
Point2D.Double redVec = new Point2D.Double();
RenderedImage refRed = null;
if(ARed != null){
// System.out.println("Drawing A");
g.drawRenderedImage(ARed, redTxf);
refRed = ARed;
}
if(BRed != null){
// System.out.println("Drawing B");
if(refRed == null){
refRed = BRed;
}
// Adjust B's coordinates
redVec.x = dx;
redVec.y = 0;
usr2dev.deltaTransform(redVec, redVec);
redVec.x = Math.floor(redVec.x) - (BRed.getMinX() - refRed.getMinX());
redVec.y = Math.floor(redVec.y) - (BRed.getMinY() - refRed.getMinY());
// System.out.println("BRed adjust : " + redVec);
// redTxf.setToTranslation(redVec.x, redVec.y);
g.drawRenderedImage(BRed, redTxf);
}
if(CRed != null){
// System.out.println("Drawing C");
if(refRed == null){
refRed = CRed;
}
// Adjust C's coordinates
redVec.x = 0;
redVec.y = dy;
usr2dev.deltaTransform(redVec, redVec);
redVec.x = Math.floor(redVec.x) - (CRed.getMinX() - refRed.getMinX());
redVec.y = Math.floor(redVec.y) - (CRed.getMinY() - refRed.getMinY());
// System.out.println("CRed adjust : " + redVec);
// redTxf.setToTranslation(redVec.x, redVec.y);
g.drawRenderedImage(CRed, redTxf);
}
if(DRed != null){
// System.out.println("Drawing D");
if(refRed == null){
refRed = DRed;
}
// Adjust D's coordinates
redVec.x = dx;
redVec.y = dy;
usr2dev.deltaTransform(redVec, redVec);
redVec.x = Math.floor(redVec.x) - (DRed.getMinX() - refRed.getMinX());
redVec.y = Math.floor(redVec.y) - (DRed.getMinY() - refRed.getMinY());
// System.out.println("DRed adjust : " + redVec);
// redTxf.setToTranslation(redVec.x, redVec.y);
g.drawRenderedImage(DRed, redTxf);
}
CachableRed realTile;
realTile = new BufferedImageCachableRed(realTileBI,
realTileRectDev.x,
realTileRectDev.y);
return realTile;
}