001: /*
002:
003: Licensed to the Apache Software Foundation (ASF) under one or more
004: contributor license agreements. See the NOTICE file distributed with
005: this work for additional information regarding copyright ownership.
006: The ASF licenses this file to You under the Apache License, Version 2.0
007: (the "License"); you may not use this file except in compliance with
008: the License. You may obtain a copy of the License at
009:
010: http://www.apache.org/licenses/LICENSE-2.0
011:
012: Unless required by applicable law or agreed to in writing, software
013: distributed under the License is distributed on an "AS IS" BASIS,
014: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: See the License for the specific language governing permissions and
016: limitations under the License.
017:
018: */
019: package org.apache.batik.ext.awt.image.renderable;
020:
021: import java.awt.Graphics2D;
022: import java.awt.RenderingHints;
023: import java.awt.Shape;
024: import java.awt.geom.AffineTransform;
025: import java.awt.geom.NoninvertibleTransformException;
026: import java.awt.geom.Rectangle2D;
027: import java.awt.image.RenderedImage;
028: import java.awt.image.renderable.RenderContext;
029:
030: import org.apache.batik.ext.awt.image.GraphicsUtil;
031:
032: /**
033: * Concrete implementation of the AffineRable interface.
034: * This adjusts the input images coordinate system by a general affine
035: *
036: * @author <a href="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
037: * @version $Id: AffineRable8Bit.java 475477 2006-11-15 22:44:28Z cam $
038: */
039: public class AffineRable8Bit extends AbstractRable implements
040: AffineRable, PaintRable {
041:
042: AffineTransform affine;
043: AffineTransform invAffine;
044:
045: public AffineRable8Bit(Filter src, AffineTransform affine) {
046: init(src);
047: setAffine(affine);
048: }
049:
050: public Rectangle2D getBounds2D() {
051: Filter src = getSource();
052: Rectangle2D r = src.getBounds2D();
053: return affine.createTransformedShape(r).getBounds2D();
054: }
055:
056: /**
057: * Returns the source to be affine.
058: */
059: public Filter getSource() {
060: return (Filter) srcs.get(0);
061: }
062:
063: /**
064: * Sets the source to be affine.
065: * @param src image to affine.
066: */
067: public void setSource(Filter src) {
068: init(src);
069: }
070:
071: /**
072: * Set the affine transform.
073: * @param affine the new Affine transform to apply.
074: */
075: public void setAffine(AffineTransform affine) {
076: touch();
077: this .affine = affine;
078: try {
079: invAffine = affine.createInverse();
080: } catch (NoninvertibleTransformException e) {
081: invAffine = null;
082: }
083: }
084:
085: /**
086: * Get the Affine.
087: * @return the Affine transform currently in effect.
088: */
089: public AffineTransform getAffine() {
090: return (AffineTransform) affine.clone();
091: }
092:
093: /**
094: * Should perform the equivilent action as
095: * createRendering followed by drawing the RenderedImage.
096: *
097: * @param g2d The Graphics2D to draw to.
098: * @return true if the paint call succeeded, false if
099: * for some reason the paint failed (in which
100: * case a createRendering should be used).
101: */
102: public boolean paintRable(Graphics2D g2d) {
103: AffineTransform at = g2d.getTransform();
104:
105: g2d.transform(getAffine());
106: GraphicsUtil.drawImage(g2d, getSource());
107:
108: g2d.setTransform(at);
109:
110: return true;
111: }
112:
113: public RenderedImage createRendering(RenderContext rc) {
114: // Degenerate Affine no output image..
115: if (invAffine == null)
116: return null;
117:
118: // Just copy over the rendering hints.
119: RenderingHints rh = rc.getRenderingHints();
120: if (rh == null)
121: rh = new RenderingHints(null);
122:
123: // Map the area of interest to our input...
124: Shape aoi = rc.getAreaOfInterest();
125: if (aoi != null)
126: aoi = invAffine.createTransformedShape(aoi);
127:
128: // update the current affine transform
129: AffineTransform at = rc.getTransform();
130: at.concatenate(affine);
131:
132: // Return what our input creates (it should factor in our affine).
133: return getSource().createRendering(
134: new RenderContext(at, aoi, rh));
135: }
136:
137: public Shape getDependencyRegion(int srcIndex, Rectangle2D outputRgn) {
138: if (srcIndex != 0)
139: throw new IndexOutOfBoundsException(
140: "Affine only has one input");
141: if (invAffine == null)
142: return null;
143: return invAffine.createTransformedShape(outputRgn);
144: }
145:
146: public Shape getDirtyRegion(int srcIndex, Rectangle2D inputRgn) {
147: if (srcIndex != 0)
148: throw new IndexOutOfBoundsException(
149: "Affine only has one input");
150: return affine.createTransformedShape(inputRgn);
151: }
152:
153: }
|