You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cf...@apache.org on 2012/10/25 21:01:49 UTC
svn commit: r1402274 [24/31] - in
/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext:
./ awt/ awt/color/ awt/font/ awt/g2d/ awt/geom/ awt/image/ awt/image/codec/
awt/image/codec/jpeg/ awt/image/codec/p...
Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/renderable/TileRable8Bit.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/renderable/TileRable8Bit.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/renderable/TileRable8Bit.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/renderable/TileRable8Bit.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,705 @@
+/*
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+package org.apache.flex.forks.batik.ext.awt.image.renderable;
+
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.RenderedImage;
+import java.awt.image.renderable.RenderContext;
+
+import org.apache.flex.forks.batik.ext.awt.RenderingHintsKeyExt;
+import org.apache.flex.forks.batik.ext.awt.image.GraphicsUtil;
+import org.apache.flex.forks.batik.ext.awt.image.rendered.AffineRed;
+import org.apache.flex.forks.batik.ext.awt.image.rendered.BufferedImageCachableRed;
+import org.apache.flex.forks.batik.ext.awt.image.rendered.CachableRed;
+import org.apache.flex.forks.batik.ext.awt.image.rendered.TileRed;
+
+/**
+ * 8 bit TileRable implementation
+ *
+ * @author <a href="mailto:vhardy@apache.org">Vincent Hardy</a>
+ * @version $Id: TileRable8Bit.java 478276 2006-11-22 18:33:37Z dvholten $
+ */
+public class TileRable8Bit
+ extends AbstractColorInterpolationRable
+ implements TileRable{
+ /**
+ * Tile region
+ */
+ private Rectangle2D tileRegion;
+
+ /**
+ * Tiled region
+ */
+ private Rectangle2D tiledRegion;
+
+ /**
+ * Controls whether the tileRegion clips the source
+ * or not
+ */
+ private boolean overflow;
+
+ /**
+ * Returns the tile region
+ */
+ public Rectangle2D getTileRegion(){
+ return tileRegion;
+ }
+
+ /**
+ * Sets the tile region
+ */
+ public void setTileRegion(Rectangle2D tileRegion){
+ if(tileRegion == null){
+ throw new IllegalArgumentException();
+ }
+ touch();
+ this.tileRegion = tileRegion;
+ }
+
+ /**
+ * Returns the tiled region
+ */
+ public Rectangle2D getTiledRegion(){
+ return tiledRegion;
+ }
+
+ /**
+ * Sets the tiled region
+ */
+ public void setTiledRegion(Rectangle2D tiledRegion){
+ if(tiledRegion == null){
+ throw new IllegalArgumentException();
+ }
+ touch();
+ this.tiledRegion = tiledRegion;
+ }
+
+ /**
+ * Returns the overflow strategy
+ */
+ public boolean isOverflow(){
+ return overflow;
+ }
+
+ /**
+ * Sets the overflow strategy
+ */
+ public void setOverflow(boolean overflow){
+ touch();
+ this.overflow = overflow;
+ }
+
+ /**
+ * Default constructor
+ */
+ public TileRable8Bit(Filter source,
+ Rectangle2D tiledRegion,
+ Rectangle2D tileRegion,
+ boolean overflow){
+ super(source);
+
+ setTileRegion(tileRegion);
+ setTiledRegion(tiledRegion);
+ setOverflow(overflow);
+ }
+
+ /**
+ * Sets the filter source
+ */
+ public void setSource(Filter src){
+ init(src);
+ }
+
+ /**
+ * Return's the tile source
+ */
+ public Filter getSource(){
+ return (Filter)srcs.get(0);
+ }
+
+ /**
+ * Returns this filter's bounds
+ */
+ public Rectangle2D getBounds2D(){
+ return (Rectangle2D)tiledRegion.clone();
+ }
+
+ public RenderedImage createRendering(RenderContext rc){
+ // Just copy over the rendering hints.
+ RenderingHints rh = rc.getRenderingHints();
+ if (rh == null) rh = new RenderingHints(null);
+
+ // update the current affine transform
+ AffineTransform at = rc.getTransform();
+
+ double sx = at.getScaleX();
+ double sy = at.getScaleY();
+
+ double shx = at.getShearX();
+ double shy = at.getShearY();
+
+ double tx = at.getTranslateX();
+ double ty = at.getTranslateY();
+
+ // The Scale is the "hypotonose" of the matrix vectors.
+ double scaleX = Math.sqrt(sx*sx + shy*shy);
+ double scaleY = Math.sqrt(sy*sy + shx*shx);
+
+ // System.out.println("AT: " + at);
+ // System.out.println("Scale: " + scaleX + "x" + scaleY);
+
+ //
+ // Compute the actual tiled area (intersection of AOI
+ // and bounds) and the actual tile (anchored in the
+ // upper left corner of the tiled area
+ //
+
+ // tiledRect
+ Rectangle2D tiledRect = getBounds2D();
+ Rectangle2D aoiRect;
+ Shape aoiShape = rc.getAreaOfInterest();
+ if (aoiShape == null)
+ aoiRect = tiledRect;
+ else {
+ aoiRect = aoiShape.getBounds2D();
+
+ if ( ! tiledRect.intersects(aoiRect) )
+ return null;
+ Rectangle2D.intersect(tiledRect, aoiRect, tiledRect);
+ }
+
+ // tileRect
+ Rectangle2D tileRect = tileRegion;
+
+ // Adjust the scale so that the tiling happens on pixel
+ // boundaries on both axis.
+ // Desired pixel rect width
+ int dw = (int)(Math.ceil(tileRect.getWidth() *scaleX));
+ int dh = (int)(Math.ceil(tileRect.getHeight()*scaleY));
+
+ double tileScaleX = dw/tileRect.getWidth();
+ double tileScaleY = dh/tileRect.getHeight();
+
+ // System.out.println("scaleX/scaleY : " + scaleX + " / " + scaleY);
+ // System.out.println("tileScaleX/tileScaleY : " + tileScaleX + " / " + tileScaleY);
+
+ // Adjust the translation so that the tile's origin falls on
+ // pixel boundary
+ int dx = (int)Math.floor(tileRect.getX()*tileScaleX);
+ int dy = (int)Math.floor(tileRect.getY()*tileScaleY);
+
+ double ttx = dx - (tileRect.getX()*tileScaleX);
+ double tty = dy - (tileRect.getY()*tileScaleY);
+
+ // System.out.println("ttx/tty : " + ttx + " / " + tty);
+
+ // Get result unsheared or rotated
+ AffineTransform tileAt;
+ // tileAt = AffineTransform.getScaleInstance(tileScaleX, tileScaleY);
+ // tileAt.translate(ttx, tty);
+ // System.out.println("Pt: " + tileAt.transform
+ // (new Point2D.Double(aoiRect.getX(),
+ // aoiRect.getY()), null));
+
+
+ tileAt = AffineTransform.getTranslateInstance(ttx, tty);
+ tileAt.scale(tileScaleX, tileScaleY);
+
+ // System.out.println("Pt: " + tileAt.transform
+ // (new Point2D.Double(aoiRect.getX(),
+ // aoiRect.getY()), null));
+
+ // System.out.println("tileRect in userSpace : " + tileRect);
+ // System.out.println("tileRect in deviceSpace : " +
+ // tileAt.createTransformedShape(tileRect).
+ // getBounds2D());
+ Filter source = getSource();
+
+ Rectangle2D srcRect;
+ if (overflow)
+ srcRect = source.getBounds2D();
+ else
+ srcRect = tileRect;
+
+ // System.out.println("SrcRect: " + srcRect);
+
+ RenderContext tileRc = new RenderContext(tileAt, srcRect, rh);
+ // RenderedImage tileRed = new DemandRed(source, tileRc);
+ RenderedImage tileRed = source.createRendering(tileRc);
+
+ // System.out.println("TileRed: " +
+ // GraphicsUtil.wrap(tileRed).getBounds());
+
+ // RenderedImage tileRed = createTile(tileRc);
+ // System.out.println("tileRed : " + tileRed.getMinX() + "/" + tileRed.getMinY() + "/"
+ // + tileRed.getWidth() + "/" + tileRed.getHeight());
+ if(tileRed == null)
+ return null;
+
+
+ // System.out.println("aoiRect: " + aoiRect);
+
+ Rectangle tiledArea = tileAt.createTransformedShape
+ (aoiRect).getBounds();
+
+ // Serious hack alert!!!
+ // In some cases the bounds are set to cover the whole area.
+ // when they get scaled up sometimes the lower bounds go
+ // to Integer.MIN_VALUE, and width/height to Integer.MAX_VALUE,
+ // but this only covers the negative quarter of the canvas!!!
+ // So if width and height are MAX_VALUE then we assume this
+ // clipping has happened and we recenter the range.
+ // Yes this is a serious hack and I appologies for it.
+ // I wouldn't need to do this if PatternPaintContext knew
+ // what it's bounds were going to be....
+ if ((tiledArea.width == Integer.MAX_VALUE)||
+ (tiledArea.height == Integer.MAX_VALUE)) {
+ tiledArea = new Rectangle(Integer.MIN_VALUE/4,
+ Integer.MIN_VALUE/4,
+ Integer.MAX_VALUE/2,
+ Integer.MAX_VALUE/2);
+ }
+ // System.out.println("tiledArea: " + tiledArea);
+ tileRed = convertSourceCS(tileRed);
+ TileRed tiledRed = new TileRed(tileRed, tiledArea, dw, dh);
+
+ // org.apache.flex.forks.batik.test.gvt.ImageDisplay.showImage("Tile", tiledRed);
+ // System.out.println("TileR: " + tiledRed.getBounds());
+
+ // Return sheared/rotated tiled image
+ AffineTransform shearAt =
+ new AffineTransform(sx/scaleX, shy/scaleX,
+ shx/scaleY, sy/scaleY,
+ tx, ty);
+ shearAt.scale(scaleX/tileScaleX, scaleY/tileScaleY);
+
+ shearAt.translate(-ttx, -tty);
+
+ CachableRed cr = tiledRed;
+ if(!shearAt.isIdentity())
+ cr = new AffineRed(tiledRed, shearAt, rh);
+
+ // System.out.println("AffineR: " + cr.getBounds());
+
+ return cr;
+ }
+
+ public Rectangle2D getActualTileBounds(Rectangle2D 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;
+
+
+ double tileWidth = tileRect.getWidth();
+ double tileHeight = tileRect.getHeight();
+
+ double tiledWidth = tiledRect.getWidth();
+ double tiledHeight = tiledRect.getHeight();
+
+ double w = Math.min(tileWidth, tiledWidth);
+ double h = Math.min(tileHeight, tiledHeight);
+
+ Rectangle2D realTileRect
+ = new Rectangle2D.Double(tileRect.getX(),
+ tileRect.getY(),
+ w, h);
+
+ return realTileRect;
+ }
+
+ /**
+ * Computes the tile to use for the tiling operation.
+ *
+ * The tile has its origin in the upper left
+ * corner of the tiled region. That tile is separated
+ * into 4 areas: top-left, top-right, bottom-left and
+ * bottom-right. Each of these areas is mapped to
+ * some input area from the source.
+ * If the source is smaller than the tiled area, then
+ * a single rendering is requested from the source.
+ * If the source's width or height is bigger than that
+ * of the tiled area, then separate renderings are
+ * requested from the source.
+ *
+ */
+ 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;
+ }
+}
Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/renderable/TileRable8Bit.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/renderable/TurbulenceRable.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/renderable/TurbulenceRable.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/renderable/TurbulenceRable.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/renderable/TurbulenceRable.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,117 @@
+/*
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+package org.apache.flex.forks.batik.ext.awt.image.renderable;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+ * Creates a sourceless image from a turbulence function.
+ *
+ * @author <a href="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
+ * @version $Id: TurbulenceRable.java 478276 2006-11-22 18:33:37Z dvholten $
+ */
+public interface TurbulenceRable extends FilterColorInterpolation {
+
+ /**
+ * Sets the turbulence region
+ * @param turbulenceRegion region to fill with turbulence function.
+ */
+ void setTurbulenceRegion(Rectangle2D turbulenceRegion);
+
+ /**
+ * Gets the turbulence region
+ */
+ Rectangle2D getTurbulenceRegion();
+
+ /**
+ * Gets the current seed value for the pseudo random number generator.
+ * @return The current seed value for the pseudo random number generator.
+ */
+ int getSeed();
+
+ /**
+ * Gets the current base fequency in x direction.
+ * @return The current base fequency in x direction.
+ */
+ double getBaseFrequencyX();
+
+ /**
+ * Gets the current base fequency in y direction.
+ * @return The current base fequency in y direction.
+ */
+ double getBaseFrequencyY();
+
+ /**
+ * Gets the current number of octaves for the noise function .
+ * @return The current number of octaves for the noise function .
+ */
+ int getNumOctaves();
+
+ /**
+ * Returns true if the turbulence function is currently stitching tiles.
+ * @return true if the turbulence function is currently stitching tiles.
+ */
+ boolean isStitched();
+
+ /**
+ * Returns true if the turbulence function is using fractal noise,
+ * instead of turbulence noise.
+ * @return true if the turbulence function is using fractal noise,
+ * instead of turbulence noise.
+ */
+ boolean isFractalNoise();
+
+ /**
+ * Sets the seed value for the pseudo random number generator.
+ * @param seed The new seed value for the pseudo random number generator.
+ */
+ void setSeed(int seed);
+
+ /**
+ * Sets the base fequency in x direction.
+ * @param xfreq The new base fequency in x direction.
+ */
+ void setBaseFrequencyX(double xfreq);
+
+ /**
+ * Sets the base fequency in y direction.
+ * @param yfreq The new base fequency in y direction.
+ */
+ void setBaseFrequencyY(double yfreq);
+
+ /**
+ * Sets the number of octaves for the noise function .
+ * @param numOctaves The new number of octaves for the noise function .
+ */
+ void setNumOctaves(int numOctaves);
+
+ /**
+ * Sets stitching state for tiles.
+ * @param stitched true if the turbulence operator should stitch tiles.
+ */
+ void setStitched(boolean stitched);
+
+ /**
+ * Turns on/off fractal noise.
+ * @param fractalNoise true if fractal noise should be used.
+ */
+ void setFractalNoise(boolean fractalNoise);
+}
+
+
Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/renderable/TurbulenceRable.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/renderable/TurbulenceRable8Bit.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/renderable/TurbulenceRable8Bit.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/renderable/TurbulenceRable8Bit.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/renderable/TurbulenceRable8Bit.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,244 @@
+/*
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+*/
+
+package org.apache.flex.forks.batik.ext.awt.image.renderable;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.RenderedImage;
+import java.awt.image.renderable.RenderContext;
+
+import org.apache.flex.forks.batik.ext.awt.image.rendered.TurbulencePatternRed;
+
+/**
+ * Creates a sourceless image from a turbulence function.
+ *
+ * @author <a href="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
+ * @version $Id: TurbulenceRable8Bit.java 478276 2006-11-22 18:33:37Z dvholten $
+ */
+public class TurbulenceRable8Bit
+ extends AbstractColorInterpolationRable
+ implements TurbulenceRable {
+
+ int seed = 0; // Seed value to pseudo rand num gen.
+ int numOctaves = 1; // number of octaves in turbulence function
+ double baseFreqX = 0; // Frequency in X/Y directions
+ double baseFreqY = 0;
+ boolean stitched = false; // True if tiles are stitched
+ boolean fractalNoise = false; // True if fractal noise should be used.
+
+ Rectangle2D region;
+
+ public TurbulenceRable8Bit(Rectangle2D region) {
+ super();
+ this.region = region;
+ }
+
+ public TurbulenceRable8Bit(Rectangle2D region,
+ int seed,
+ int numOctaves,
+ double baseFreqX,
+ double baseFreqY,
+ boolean stitched,
+ boolean fractalNoise) {
+ super();
+ this.seed = seed;
+ this.numOctaves = numOctaves;
+ this.baseFreqX = baseFreqX;
+ this.baseFreqY = baseFreqY;
+ this.stitched = stitched;
+ this.fractalNoise = fractalNoise;
+ this.region = region;
+ }
+
+ /**
+ * Get the turbulence region
+ */
+ public Rectangle2D getTurbulenceRegion() {
+ return (Rectangle2D)region.clone();
+ }
+
+ /**
+ * Get the turbulence region
+ */
+ public Rectangle2D getBounds2D() {
+ return (Rectangle2D)region.clone();
+ }
+
+ /**
+ * Get the current seed value for the pseudo random number generator.
+ * @return The current seed value for the pseudo random number generator.
+ */
+ public int getSeed() {
+ return seed;
+ }
+
+ /**
+ * Get the current number of octaves for the noise function .
+ * @return The current number of octaves for the noise function .
+ */
+ public int getNumOctaves() {
+ return numOctaves;
+ }
+
+ /**
+ * Get the current base fequency in x direction.
+ * @return The current base fequency in x direction.
+ */
+ public double getBaseFrequencyX() {
+ return baseFreqX;
+ }
+
+ /**
+ * Get the current base fequency in y direction.
+ * @return The current base fequency in y direction.
+ */
+ public double getBaseFrequencyY() {
+ return baseFreqY;
+ }
+
+ /**
+ * Returns true if the turbulence function is currently stitching tiles.
+ * @return true if the turbulence function is currently stitching tiles.
+ */
+ public boolean isStitched() {
+ return stitched;
+ }
+
+ /**
+ * Returns true if the turbulence function is using fractal noise,
+ * instead of turbulence noise.
+ * @return true if the turbulence function is using fractal noise,
+ * instead of turbulence noise.
+ */
+ public boolean isFractalNoise() {
+ return fractalNoise;
+ }
+
+ /**
+ * Sets the turbulence region
+ * @param turbulenceRegion region to fill with turbulence function.
+ */
+ public void setTurbulenceRegion(Rectangle2D turbulenceRegion) {
+ touch();
+ this.region = turbulenceRegion;
+ }
+
+ /**
+ * Set the seed value for the pseudo random number generator.
+ * @param seed The new seed value for the pseudo random number generator.
+ */
+ public void setSeed(int seed) {
+ touch();
+ this.seed = seed;
+ }
+
+ /**
+ * Set the number of octaves for the noise function .
+ * @param numOctaves The new number of octaves for the noise function .
+ */
+ public void setNumOctaves(int numOctaves) {
+ touch();
+ this.numOctaves = numOctaves;
+ }
+
+ /**
+ * Set the base fequency in x direction.
+ * @param baseFreqX The new base fequency in x direction.
+ */
+ public void setBaseFrequencyX(double baseFreqX) {
+ touch();
+ this.baseFreqX = baseFreqX;
+ }
+
+ /**
+ * Set the base fequency in y direction.
+ * @param baseFreqY The new base fequency in y direction.
+ */
+ public void setBaseFrequencyY(double baseFreqY) {
+ touch();
+ this.baseFreqY = baseFreqY;
+ }
+
+ /**
+ * Set stitching state for tiles.
+ * @param stitched true if the turbulence operator should stitch tiles.
+ */
+ public void setStitched(boolean stitched) {
+ touch();
+ this.stitched = stitched;
+ }
+
+ /**
+ * Turns on/off fractal noise.
+ * @param fractalNoise true if fractal noise should be used.
+ */
+ public void setFractalNoise(boolean fractalNoise) {
+ touch();
+ this.fractalNoise = fractalNoise;
+ }
+
+ public RenderedImage createRendering(RenderContext rc){
+
+ Rectangle2D aoiRect;
+ Shape aoi = rc.getAreaOfInterest();
+ if(aoi == null){
+ aoiRect = getBounds2D();
+ } else {
+ Rectangle2D rect = getBounds2D();
+ aoiRect = aoi.getBounds2D();
+ if ( ! aoiRect.intersects(rect) )
+ return null;
+ Rectangle2D.intersect(aoiRect, rect, aoiRect);
+ }
+
+ AffineTransform usr2dev = rc.getTransform();
+
+ // Compute size of raster image in device space.
+ // System.out.println("Turbulence aoi : " + aoi);
+ // System.out.println("Scale X : " + usr2dev.getScaleX() + " scaleY : " + usr2dev.getScaleY());
+ // System.out.println("Turbulence aoi dev : " + usr2dev.createTransformedShape(aoi).getBounds());
+ final Rectangle devRect
+ = usr2dev.createTransformedShape(aoiRect).getBounds();
+
+ if ((devRect.width <= 0) ||
+ (devRect.height <= 0))
+ return null;
+
+ ColorSpace cs = getOperationColorSpace();
+
+ Rectangle2D tile = null;
+ if (stitched)
+ tile = (Rectangle2D)region.clone();
+
+ AffineTransform patternTxf = new AffineTransform();
+ try{
+ patternTxf = usr2dev.createInverse();
+ }catch(NoninvertibleTransformException e){
+ }
+
+ return new TurbulencePatternRed
+ (baseFreqX, baseFreqY, numOctaves, seed, fractalNoise,
+ tile, patternTxf, devRect, cs, true);
+ }
+}
Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/renderable/TurbulenceRable8Bit.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/AbstractRed.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/AbstractRed.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/AbstractRed.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/AbstractRed.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,667 @@
+/*
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+package org.apache.flex.forks.batik.ext.awt.image.rendered;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+import org.apache.flex.forks.batik.ext.awt.image.GraphicsUtil;
+
+
+// import org.apache.flex.forks.batik.ext.awt.image.DataBufferReclaimer;
+// import java.awt.image.DataBufferInt;
+// import java.awt.image.SinglePixelPackedSampleModel;
+
+
+/**
+ * This is an abstract base class that takes care of most of the
+ * normal issues surrounding the implementation of the CachableRed
+ * (RenderedImage) interface. It tries to make no assumptions about
+ * the subclass implementation.
+ *
+ * @author <a href="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
+ * @version $Id: AbstractRed.java 489226 2006-12-21 00:05:36Z cam $
+ */
+public abstract class AbstractRed implements CachableRed {
+
+ protected Rectangle bounds;
+ protected Vector srcs;
+ protected Map props;
+ protected SampleModel sm;
+ protected ColorModel cm;
+ protected int tileGridXOff, tileGridYOff;
+ protected int tileWidth, tileHeight;
+ protected int minTileX, minTileY;
+ protected int numXTiles, numYTiles;
+
+ /**
+ * void constructor. The subclass must call one of the
+ * flavors of init before the object becomes usable.
+ * This is useful when the proper parameters to the init
+ * method need to be computed in the subclasses constructor.
+ */
+ protected AbstractRed() {
+ }
+
+
+ /**
+ * Construct an Abstract RenderedImage from a bounds rect and props
+ * (may be null). The srcs Vector will be empty.
+ * @param bounds this defines the extent of the rable in the
+ * user coordinate system.
+ * @param props this initializes the props Map (may be null)
+ */
+ protected AbstractRed(Rectangle bounds, Map props) {
+ init((CachableRed)null, bounds, null, null,
+ bounds.x, bounds.y, props);
+ }
+
+ /**
+ * Construct an Abstract RenderedImage from a source image and
+ * props (may be null).
+ * @param src will be the first (and only) member of the srcs
+ * Vector. Src is also used to set the bounds, ColorModel,
+ * SampleModel, and tile grid offsets.
+ * @param props this initializes the props Map. */
+ protected AbstractRed(CachableRed src, Map props) {
+ init(src, src.getBounds(), src.getColorModel(), src.getSampleModel(),
+ src.getTileGridXOffset(),
+ src.getTileGridYOffset(),
+ props);
+ }
+
+ /**
+ * Construct an Abstract RenderedImage from a source image, bounds
+ * rect and props (may be null).
+ * @param src will be the first (and only) member of the srcs
+ * Vector. Src is also used to set the ColorModel, SampleModel,
+ * and tile grid offsets.
+ * @param bounds The bounds of this image.
+ * @param props this initializes the props Map. */
+ protected AbstractRed(CachableRed src, Rectangle bounds, Map props) {
+ init(src, bounds, src.getColorModel(), src.getSampleModel(),
+ src.getTileGridXOffset(),
+ src.getTileGridYOffset(),
+ props);
+ }
+
+ /**
+ * Construct an Abstract RenderedImage from a source image, bounds
+ * rect and props (may be null).
+ * @param src if not null, will be the first (and only) member
+ * of the srcs Vector. Also if it is not null it provides the
+ * tile grid offsets, otherwise they are zero.
+ * @param bounds The bounds of this image.
+ * @param cm The ColorModel to use. If null it will default to
+ * ComponentColorModel.
+ * @param sm The sample model to use. If null it will construct
+ * a sample model the matches the given/generated ColorModel and is
+ * the size of bounds.
+ * @param props this initializes the props Map. */
+ protected AbstractRed(CachableRed src, Rectangle bounds,
+ ColorModel cm, SampleModel sm,
+ Map props) {
+ init(src, bounds, cm, sm,
+ (src==null)?0:src.getTileGridXOffset(),
+ (src==null)?0:src.getTileGridYOffset(),
+ props);
+ }
+
+ /**
+ * Construct an Abstract Rable from a bounds rect and props
+ * (may be null). The srcs Vector will be empty.
+ * @param src will be the first (and only) member of the srcs
+ * Vector. Src is also used to set the ColorModel, SampleModel,
+ * and tile grid offsets.
+ * @param bounds this defines the extent of the rable in the
+ * user coordinate system.
+ * @param cm The ColorModel to use. If null it will default to
+ * ComponentColorModel.
+ * @param sm The sample model to use. If null it will construct
+ * a sample model the matches the given/generated ColorModel and is
+ * the size of bounds.
+ * @param tileGridXOff The x location of tile 0,0.
+ * @param tileGridYOff The y location of tile 0,0.
+ * @param props this initializes the props Map.
+ */
+ protected AbstractRed(CachableRed src, Rectangle bounds,
+ ColorModel cm, SampleModel sm,
+ int tileGridXOff, int tileGridYOff,
+ Map props) {
+ init(src, bounds, cm, sm, tileGridXOff, tileGridYOff, props);
+ }
+
+ /**
+ * This is one of two basic init function (this is for single
+ * source rendereds).
+ * It is provided so subclasses can compute various values
+ * before initializing all the state in the base class.
+ * You really should call this method before returning from
+ * your subclass constructor.
+ *
+ * @param src The source for the filter
+ * @param bounds The bounds of the image
+ * @param cm The ColorModel to use. If null it defaults to
+ * ComponentColorModel/ src's ColorModel.
+ * @param sm The Sample modle to use. If this is null it will
+ * use the src's sample model if that is null it will
+ * construct a sample model that matches the ColorModel
+ * and is the size of the whole image.
+ * @param tileGridXOff The x location of tile 0,0.
+ * @param tileGridYOff The y location of tile 0,0.
+ * @param props Any properties you want to associate with the image.
+ */
+ protected void init(CachableRed src, Rectangle bounds,
+ ColorModel cm, SampleModel sm,
+ int tileGridXOff, int tileGridYOff,
+ Map props) {
+ this.srcs = new Vector(1);
+ if (src != null) {
+ this.srcs.add(src);
+ if (bounds == null) bounds = src.getBounds();
+ if (cm == null) cm = src.getColorModel();
+ if (sm == null) sm = src.getSampleModel();
+ }
+
+ this.bounds = bounds;
+ this.tileGridXOff = tileGridXOff;
+ this.tileGridYOff = tileGridYOff;
+
+ this.props = new HashMap();
+ if(props != null){
+ this.props.putAll(props);
+ }
+
+ if (cm == null)
+ cm = new ComponentColorModel
+ (ColorSpace.getInstance(ColorSpace.CS_GRAY),
+ new int [] { 8 }, false, false, Transparency.OPAQUE,
+ DataBuffer.TYPE_BYTE);
+
+ this.cm = cm;
+
+ if (sm == null)
+ sm = cm.createCompatibleSampleModel(bounds.width, bounds.height);
+ this.sm = sm;
+
+ // Recompute tileWidth/Height, minTileX/Y, numX/YTiles.
+ updateTileGridInfo();
+ }
+
+ /**
+ * Construct an Abstract Rable from a List of sources a bounds rect
+ * and props (may be null).
+ * @param srcs This is used to initialize the srcs Vector. All
+ * the members of srcs must be CachableRed otherwise an error
+ * will be thrown.
+ * @param bounds this defines the extent of the rendered in pixels
+ * @param props this initializes the props Map.
+ */
+ protected AbstractRed(List srcs, Rectangle bounds, Map props) {
+ init(srcs, bounds, null, null, bounds.x, bounds.y, props);
+ }
+
+ /**
+ * Construct an Abstract RenderedImage from a bounds rect,
+ * ColorModel (may be null), SampleModel (may be null) and props
+ * (may be null). The srcs Vector will be empty.
+ * @param srcs This is used to initialize the srcs Vector. All
+ * the members of srcs must be CachableRed otherwise an error
+ * will be thrown.
+ * @param bounds this defines the extent of the rendered in pixels
+ * @param cm The ColorModel to use. If null it will default to
+ * ComponentColorModel.
+ * @param sm The sample model to use. If null it will construct
+ * a sample model the matches the given/generated ColorModel and is
+ * the size of bounds.
+ * @param props this initializes the props Map.
+ */
+ protected AbstractRed(List srcs, Rectangle bounds,
+ ColorModel cm, SampleModel sm,
+ Map props) {
+ init(srcs, bounds, cm, sm, bounds.x, bounds.y, props);
+ }
+
+ /**
+ * Construct an Abstract RenderedImage from a bounds rect,
+ * ColorModel (may be null), SampleModel (may be null), tile grid
+ * offsets and props (may be null). The srcs Vector will be
+ * empty.
+ * @param srcs This is used to initialize the srcs Vector. All
+ * the members of srcs must be CachableRed otherwise an error
+ * will be thrown.
+ * @param bounds this defines the extent of the rable in the
+ * user coordinate system.
+ * @param cm The ColorModel to use. If null it will default to
+ * ComponentColorModel.
+ * @param sm The sample model to use. If null it will construct
+ * a sample model the matches the given/generated ColorModel and is
+ * the size of bounds.
+ * @param tileGridXOff The x location of tile 0,0.
+ * @param tileGridYOff The y location of tile 0,0.
+ * @param props this initializes the props Map.
+ */
+ protected AbstractRed(List srcs, Rectangle bounds,
+ ColorModel cm, SampleModel sm,
+ int tileGridXOff, int tileGridYOff,
+ Map props) {
+ init(srcs, bounds, cm, sm, tileGridXOff, tileGridYOff, props);
+ }
+
+ /**
+ * This is the basic init function.
+ * It is provided so subclasses can compute various values
+ * before initializing all the state in the base class.
+ * You really should call this method before returning from
+ * your subclass constructor.
+ *
+ * @param srcs The list of sources
+ * @param bounds The bounds of the image
+ * @param cm The ColorModel to use. If null it defaults to
+ * ComponentColorModel.
+ * @param sm The Sample modle to use. If this is null it will
+ * construct a sample model that matches the ColorModel
+ * and is the size of the whole image.
+ * @param tileGridXOff The x location of tile 0,0.
+ * @param tileGridYOff The y location of tile 0,0.
+ * @param props Any properties you want to associate with the image.
+ */
+ protected void init(List srcs, Rectangle bounds,
+ ColorModel cm, SampleModel sm,
+ int tileGridXOff, int tileGridYOff,
+ Map props) {
+ this.srcs = new Vector();
+ if(srcs != null){
+ this.srcs.addAll(srcs);
+ }
+
+ if (srcs.size() != 0) {
+ CachableRed src = (CachableRed)srcs.get(0);
+ if (bounds == null) bounds = src.getBounds();
+ if (cm == null) cm = src.getColorModel();
+ if (sm == null) sm = src.getSampleModel();
+ }
+
+ this.bounds = bounds;
+ this.tileGridXOff = tileGridXOff;
+ this.tileGridYOff = tileGridYOff;
+ this.props = new HashMap();
+ if(props != null){
+ this.props.putAll(props);
+ }
+
+ if (cm == null)
+ cm = new ComponentColorModel
+ (ColorSpace.getInstance(ColorSpace.CS_GRAY),
+ new int [] { 8 }, false, false, Transparency.OPAQUE,
+ DataBuffer.TYPE_BYTE);
+
+ this.cm = cm;
+
+ if (sm == null)
+ sm = cm.createCompatibleSampleModel(bounds.width, bounds.height);
+ this.sm = sm;
+
+ // Recompute tileWidth/Height, minTileX/Y, numX/YTiles.
+ updateTileGridInfo();
+ }
+
+ /**
+ * This function computes all the basic information about the tile
+ * grid based on the data stored in sm, and tileGridX/YOff.
+ * It is responsible for updating tileWidth, tileHeight,
+ * minTileX/Y, and numX/YTiles.
+ */
+ protected void updateTileGridInfo() {
+ this.tileWidth = sm.getWidth();
+ this.tileHeight = sm.getHeight();
+
+ int x1, y1, maxTileX, maxTileY;
+
+ // This computes and caches important information about the
+ // structure of the tile grid in general.
+ minTileX = getXTile(bounds.x);
+ minTileY = getYTile(bounds.y);
+
+ x1 = bounds.x + bounds.width-1; // Xloc of right edge
+ maxTileX = getXTile(x1);
+ numXTiles = maxTileX-minTileX+1;
+
+ y1 = bounds.y + bounds.height-1; // Yloc of right edge
+ maxTileY = getYTile(y1);
+ numYTiles = maxTileY-minTileY+1;
+ }
+
+
+ public Rectangle getBounds() {
+ return new Rectangle(getMinX(),
+ getMinY(),
+ getWidth(),
+ getHeight());
+ }
+
+ public Vector getSources() {
+ return srcs;
+ }
+
+ public ColorModel getColorModel() {
+ return cm;
+ }
+
+ public SampleModel getSampleModel() {
+ return sm;
+ }
+
+ public int getMinX() {
+ return bounds.x;
+ }
+ public int getMinY() {
+ return bounds.y;
+ }
+
+ public int getWidth() {
+ return bounds.width;
+ }
+
+ public int getHeight() {
+ return bounds.height;
+ }
+
+ public int getTileWidth() {
+ return tileWidth;
+ }
+
+ public int getTileHeight() {
+ return tileHeight;
+ }
+
+ public int getTileGridXOffset() {
+ return tileGridXOff;
+ }
+
+ public int getTileGridYOffset() {
+ return tileGridYOff;
+ }
+
+ public int getMinTileX() {
+ return minTileX;
+ }
+
+ public int getMinTileY() {
+ return minTileY;
+ }
+
+ public int getNumXTiles() {
+ return numXTiles;
+ }
+
+ public int getNumYTiles() {
+ return numYTiles;
+ }
+
+ public Object getProperty(String name) {
+ Object ret = props.get(name);
+ if (ret != null) return ret;
+ Iterator i = srcs.iterator();
+ while (i.hasNext()) {
+ RenderedImage ri = (RenderedImage)i.next();
+ ret = ri.getProperty(name);
+ if (ret != null) return ret;
+ }
+ return null;
+ }
+
+ public String [] getPropertyNames() {
+ Set keys = props.keySet();
+ String[] ret = new String[keys.size()];
+ keys.toArray( ret );
+
+// Iterator iter = keys.iterator();
+// int i=0;
+// while (iter.hasNext()) {
+// ret[i++] = (String)iter.next();
+// }
+
+ Iterator iter = srcs.iterator();
+ while (iter.hasNext()) {
+ RenderedImage ri = (RenderedImage)iter.next();
+ String [] srcProps = ri.getPropertyNames();
+ if (srcProps.length != 0) {
+ String [] tmp = new String[ret.length+srcProps.length];
+ System.arraycopy(ret,0,tmp,0,ret.length);
+ /// ??? System.arraycopy((tmp,ret.length,srcProps,0,srcProps.length);
+ System.arraycopy( srcProps, 0, tmp, ret.length, srcProps.length);
+ ret = tmp;
+ }
+ }
+
+ return ret;
+ }
+
+ public Shape getDependencyRegion(int srcIndex, Rectangle outputRgn) {
+ if ((srcIndex < 0) || (srcIndex > srcs.size()))
+ throw new IndexOutOfBoundsException
+ ("Nonexistant source requested.");
+
+ // Return empty rect if they don't intersect.
+ if ( ! outputRgn.intersects(bounds) )
+ return new Rectangle();
+
+ // We only depend on our source for stuff that is inside
+ // our bounds...
+ return outputRgn.intersection(bounds);
+ }
+
+ public Shape getDirtyRegion(int srcIndex, Rectangle inputRgn) {
+ if (srcIndex != 0)
+ throw new IndexOutOfBoundsException
+ ("Nonexistant source requested.");
+
+ // Return empty rect if they don't intersect.
+ if ( ! inputRgn.intersects(bounds) )
+ return new Rectangle();
+
+ // Changes in the input region don't propogate outside our
+ // bounds.
+ return inputRgn.intersection(bounds);
+ }
+
+
+ // This is not included but can be implemented by the following.
+ // In which case you _must_ reimplement getTile.
+ // public WritableRaster copyData(WritableRaster wr) {
+ // copyToRaster(wr);
+ // return wr;
+ // }
+
+ public Raster getTile(int tileX, int tileY) {
+ WritableRaster wr = makeTile(tileX, tileY);
+ return copyData(wr);
+ }
+
+ public Raster getData() {
+ return getData(bounds);
+ }
+
+ public Raster getData(Rectangle rect) {
+ SampleModel smRet = sm.createCompatibleSampleModel
+ (rect.width, rect.height);
+
+ Point pt = new Point(rect.x, rect.y);
+ WritableRaster wr = Raster.createWritableRaster(smRet, pt);
+
+ // System.out.println("GD DB: " + wr.getDataBuffer().getSize());
+ return copyData(wr);
+ }
+
+ /**
+ * Returns the x index of tile under xloc.
+ * @param xloc the x location (in pixels) to get tile for.
+ * @return The tile index under xloc (may be outside tile grid).
+ */
+ public final int getXTile(int xloc) {
+ int tgx = xloc-tileGridXOff;
+ // We need to round to -infinity...
+ if (tgx>=0)
+ return tgx/tileWidth;
+ else
+ return (tgx-tileWidth+1)/tileWidth;
+ }
+
+ /**
+ * Returns the y index of tile under yloc.
+ * @param yloc the y location (in pixels) to get tile for.
+ * @return The tile index under yloc (may be outside tile grid).
+ */
+ public final int getYTile(int yloc) {
+ int tgy = yloc-tileGridYOff;
+ // We need to round to -infinity...
+ if (tgy>=0)
+ return tgy/tileHeight;
+ else
+ return (tgy-tileHeight+1)/tileHeight;
+ }
+
+ /**
+ * Copies data from this images tile grid into wr. wr may
+ * extend outside the bounds of this image in which case the
+ * data in wr outside the bounds will not be touched.
+ * @param wr Raster to fill with image data.
+ */
+ public void copyToRaster(WritableRaster wr) {
+ int tx0 = getXTile(wr.getMinX());
+ int ty0 = getYTile(wr.getMinY());
+ int tx1 = getXTile(wr.getMinX()+wr.getWidth() -1);
+ int ty1 = getYTile(wr.getMinY()+wr.getHeight()-1);
+
+ if (tx0 < minTileX) tx0 = minTileX;
+ if (ty0 < minTileY) ty0 = minTileY;
+
+ if (tx1 >= minTileX+numXTiles) tx1 = minTileX+numXTiles-1;
+ if (ty1 >= minTileY+numYTiles) ty1 = minTileY+numYTiles-1;
+
+ final boolean is_INT_PACK =
+ GraphicsUtil.is_INT_PACK_Data(getSampleModel(), false);
+
+ for (int y=ty0; y<=ty1; y++)
+ for (int x=tx0; x<=tx1; x++) {
+ Raster r = getTile(x, y);
+ if (is_INT_PACK)
+ GraphicsUtil.copyData_INT_PACK(r, wr);
+ else
+ GraphicsUtil.copyData_FALLBACK(r, wr);
+ }
+ }
+
+
+ // static DataBufferReclaimer reclaim = new DataBufferReclaimer();
+
+ /**
+ * This is a helper function that will create the tile requested
+ * Including properly subsetting the bounds of the tile to the
+ * bounds of the current image.
+ * @param tileX The x index of the tile to be built
+ * @param tileY The y index of the tile to be built
+ * @return The tile requested
+ * @exception IndexOutOfBoundsException if the requested tile index
+ * falles outside of the bounds of the tile grid for the image.
+ */
+ public WritableRaster makeTile(int tileX, int tileY) {
+ if ((tileX < minTileX) || (tileX >= minTileX+numXTiles) ||
+ (tileY < minTileY) || (tileY >= minTileY+numYTiles))
+ throw new IndexOutOfBoundsException
+ ("Requested Tile (" + tileX + ',' + tileY +
+ ") lies outside the bounds of image");
+
+ Point pt = new Point(tileGridXOff+tileX*tileWidth,
+ tileGridYOff+tileY*tileHeight);
+
+ WritableRaster wr;
+ wr = Raster.createWritableRaster(sm, pt);
+ // if (!(sm instanceof SinglePixelPackedSampleModel))
+ // wr = Raster.createWritableRaster(sm, pt);
+ // else {
+ // SinglePixelPackedSampleModel sppsm;
+ // sppsm = (SinglePixelPackedSampleModel)sm;
+ // int stride = sppsm.getScanlineStride();
+ // int sz = stride*sppsm.getHeight();
+ //
+ // int [] data = reclaim.request(sz);
+ // DataBuffer db = new DataBufferInt(data, sz);
+ //
+ // reclaim.register(db);
+ //
+ // wr = Raster.createWritableRaster(sm, db, pt);
+ // }
+
+ // System.out.println("MT DB: " + wr.getDataBuffer().getSize());
+
+ int x0 = wr.getMinX();
+ int y0 = wr.getMinY();
+ int x1 = x0+wr.getWidth() -1;
+ int y1 = y0+wr.getHeight()-1;
+
+ if ((x0 < bounds.x) || (x1 >= (bounds.x+bounds.width)) ||
+ (y0 < bounds.y) || (y1 >= (bounds.y+bounds.height))) {
+ // Part of this raster lies outside our bounds so subset
+ // it so it only advertises the stuff inside our bounds.
+ if (x0 < bounds.x) x0 = bounds.x;
+ if (y0 < bounds.y) y0 = bounds.y;
+ if (x1 >= (bounds.x+bounds.width)) x1 = bounds.x+bounds.width-1;
+ if (y1 >= (bounds.y+bounds.height)) y1 = bounds.y+bounds.height-1;
+
+ wr = wr.createWritableChild(x0, y0, x1-x0+1, y1-y0+1,
+ x0, y0, null);
+ }
+ return wr;
+ }
+
+ public static void copyBand(Raster src, int srcBand,
+ WritableRaster dst, int dstBand) {
+ Rectangle srcR = new Rectangle(src.getMinX(), src.getMinY(),
+ src.getWidth(), src.getHeight());
+ Rectangle dstR = new Rectangle(dst.getMinX(), dst.getMinY(),
+ dst.getWidth(), dst.getHeight());
+
+ Rectangle cpR = srcR.intersection(dstR);
+
+ int [] samples = null;
+ for (int y=cpR.y; y< cpR.y+cpR.height; y++) {
+ samples = src.getSamples(cpR.x, y, cpR.width, 1, srcBand, samples);
+ dst.setSamples(cpR.x, y, cpR.width, 1, dstBand, samples);
+ }
+ }
+}
+
Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/rendered/AbstractRed.java
------------------------------------------------------------------------------
svn:eol-style = native