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.Composite;
022: import java.awt.Graphics2D;
023: import java.awt.Rectangle;
024: import java.awt.RenderingHints;
025: import java.awt.Shape;
026: import java.awt.color.ColorSpace;
027: import java.awt.geom.AffineTransform;
028: import java.awt.geom.Rectangle2D;
029: import java.awt.image.RenderedImage;
030: import java.awt.image.renderable.RenderContext;
031: import java.util.Iterator;
032: import java.util.List;
033: import java.util.ArrayList;
034:
035: import org.apache.batik.ext.awt.image.CompositeRule;
036: import org.apache.batik.ext.awt.image.GraphicsUtil;
037: import org.apache.batik.ext.awt.image.SVGComposite;
038: import org.apache.batik.ext.awt.image.rendered.CachableRed;
039: import org.apache.batik.ext.awt.image.rendered.CompositeRed;
040: import org.apache.batik.ext.awt.image.rendered.FloodRed;
041:
042: /**
043: * Composites a list of images according to a single composite rule.
044: * the image are applied in the order they are in the List given.
045: *
046: * @author <a href="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
047: * @version $Id: CompositeRable8Bit.java 489226 2006-12-21 00:05:36Z cam $
048: */
049: public class CompositeRable8Bit extends AbstractColorInterpolationRable
050: implements CompositeRable, PaintRable {
051:
052: protected CompositeRule rule;
053:
054: public CompositeRable8Bit(List srcs, CompositeRule rule,
055: boolean csIsLinear) {
056: super (srcs);
057:
058: setColorSpaceLinear(csIsLinear);
059:
060: this .rule = rule;
061: }
062:
063: /**
064: * The sources to be composited togeather.
065: * @param srcs The list of images to be composited by the composite rule.
066: */
067: public void setSources(List srcs) {
068: init(srcs, null);
069: }
070:
071: /**
072: * Set the composite rule to use for combining the sources.
073: * @param cr Composite rule to use.
074: */
075: public void setCompositeRule(CompositeRule cr) {
076: touch();
077: this .rule = cr;
078: }
079:
080: /**
081: * Get the composite rule in use for combining the sources.
082: * @return Composite rule currently in use.
083: */
084: public CompositeRule getCompositeRule() {
085: return this .rule;
086: }
087:
088: /**
089: * Should perform the equivilent action as
090: * createRendering followed by drawing the RenderedImage to
091: * Graphics2D, or return false.
092: *
093: * @param g2d The Graphics2D to draw to.
094: * @return true if the paint call succeeded, false if
095: * for some reason the paint failed (in which
096: * case a createRendering should be used).
097: */
098: public boolean paintRable(Graphics2D g2d) {
099: // This optimization only apply if we are using
100: // SrcOver. Otherwise things break...
101: Composite c = g2d.getComposite();
102: if (!SVGComposite.OVER.equals(c))
103: return false;
104:
105: // For the over mode we can just draw them in order...
106: if (getCompositeRule() != CompositeRule.OVER)
107: return false;
108:
109: ColorSpace crCS = getOperationColorSpace();
110: ColorSpace g2dCS = GraphicsUtil.getDestinationColorSpace(g2d);
111: if ((g2dCS == null) || (g2dCS != crCS)) {
112: return false;
113: }
114:
115: // System.out.println("drawImage : " + g2dCS +
116: // crCS);
117: Iterator i = getSources().iterator();
118: while (i.hasNext()) {
119: GraphicsUtil.drawImage(g2d, (Filter) i.next());
120: }
121: return true;
122: }
123:
124: public RenderedImage createRendering(RenderContext rc) {
125: if (srcs.size() == 0)
126: return null;
127:
128: // Just copy over the rendering hints.
129: RenderingHints rh = rc.getRenderingHints();
130: if (rh == null)
131: rh = new RenderingHints(null);
132:
133: // update the current affine transform
134: AffineTransform at = rc.getTransform();
135:
136: Shape aoi = rc.getAreaOfInterest();
137: Rectangle2D aoiR;
138: if (aoi == null)
139: aoiR = getBounds2D();
140: else {
141: aoiR = aoi.getBounds2D();
142: Rectangle2D bounds2d = getBounds2D();
143: if (!bounds2d.intersects(aoiR))
144: return null;
145:
146: Rectangle2D.intersect(aoiR, bounds2d, aoiR);
147: }
148:
149: Rectangle devRect = at.createTransformedShape(aoiR).getBounds();
150:
151: rc = new RenderContext(at, aoiR, rh);
152:
153: // note: this hides a member in a superclass!
154: List srcs = new ArrayList();
155:
156: Iterator i = getSources().iterator();
157: while (i.hasNext()) {
158: // Get the source to work with...
159: Filter filt = (Filter) i.next();
160:
161: // Get our sources image...
162: RenderedImage ri = filt.createRendering(rc);
163: if (ri != null) {
164: CachableRed cr;
165: cr = convertSourceCS(ri);
166: srcs.add(cr);
167: } else {
168:
169: // Blank image...
170: switch (rule.getRule()) {
171: case CompositeRule.RULE_IN:
172: // For Mode IN One blank image kills all output
173: // (including any "future" images to be drawn).
174: return null;
175:
176: case CompositeRule.RULE_OUT:
177: // For mode OUT blank image clears output
178: // up to this point, so ignore inputs to this point.
179: srcs.clear();
180: break;
181:
182: case CompositeRule.RULE_ARITHMETIC:
183: srcs.add(new FloodRed(devRect));
184: break;
185:
186: default:
187: // All other cases we simple pretend the image didn't
188: // exist (fully transparent image has no affect).
189: break;
190: }
191: }
192: }
193:
194: if (srcs.size() == 0)
195: return null;
196:
197: // System.out.println("Done General: " + rule);
198: CachableRed cr = new CompositeRed(srcs, rule);
199: return cr;
200: }
201: }
|