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