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.gvt.filter;
020:
021: import java.awt.geom.Rectangle2D;
022: import java.awt.image.RenderedImage;
023: import java.awt.image.renderable.RenderContext;
024:
025: import org.apache.batik.ext.awt.image.GraphicsUtil;
026: import org.apache.batik.ext.awt.image.PadMode;
027: import org.apache.batik.ext.awt.image.renderable.AbstractRable;
028: import org.apache.batik.ext.awt.image.renderable.Filter;
029: import org.apache.batik.ext.awt.image.renderable.FilterAsAlphaRable;
030: import org.apache.batik.ext.awt.image.renderable.PadRable;
031: import org.apache.batik.ext.awt.image.renderable.PadRable8Bit;
032: import org.apache.batik.ext.awt.image.rendered.CachableRed;
033: import org.apache.batik.ext.awt.image.rendered.MultiplyAlphaRed;
034: import org.apache.batik.ext.awt.image.rendered.RenderedImageCachableRed;
035: import org.apache.batik.gvt.GraphicsNode;
036:
037: /**
038: * MaskRable implementation
039: *
040: * @author <a href="mailto:Thomas.DeWeese@Kodak.com">Thomas DeWeese</a>
041: * @version $Id: MaskRable8Bit.java 475477 2006-11-15 22:44:28Z cam $
042: */
043: public class MaskRable8Bit extends AbstractRable implements Mask {
044:
045: /**
046: * The node who's outline specifies our mask.
047: */
048: protected GraphicsNode mask;
049:
050: /**
051: * Region to which the mask applies
052: */
053: protected Rectangle2D filterRegion;
054:
055: public MaskRable8Bit(Filter src, GraphicsNode mask,
056: Rectangle2D filterRegion) {
057: super (src, null);
058: setMaskNode(mask);
059: setFilterRegion(filterRegion);
060: }
061:
062: /**
063: * The source to be masked by the mask node.
064: * @param src The Image to be masked.
065: */
066: public void setSource(Filter src) {
067: init(src, null);
068: }
069:
070: /**
071: * This returns the current image being masked by the mask node.
072: * @return The image to mask
073: */
074: public Filter getSource() {
075: return (Filter) getSources().get(0);
076: }
077:
078: /**
079: * The region to which this mask applies
080: */
081: public Rectangle2D getFilterRegion() {
082: return (Rectangle2D) filterRegion.clone();
083: }
084:
085: /**
086: * Returns the filter region to which this mask applies
087: */
088: public void setFilterRegion(Rectangle2D filterRegion) {
089: if (filterRegion == null) {
090: throw new IllegalArgumentException();
091: }
092:
093: this .filterRegion = filterRegion;
094: }
095:
096: /**
097: * Set the masking image to that described by gn.
098: * If gn is an rgba image then the alpha is premultiplied and then
099: * the rgb is converted to alpha via the standard feColorMatrix
100: * rgb to luminance conversion.
101: * In the case of an rgb only image, just the rgb to luminance
102: * conversion is performed.
103: * @param mask The graphics node that defines the mask image.
104: */
105: public void setMaskNode(GraphicsNode mask) {
106: touch();
107: this .mask = mask;
108: }
109:
110: /**
111: * Returns the Graphics node that the mask operation will use to
112: * define the masking image.
113: * @return The graphics node that defines the mask image.
114: */
115: public GraphicsNode getMaskNode() {
116: return mask;
117: }
118:
119: /**
120: * Pass-through: returns the source's bounds
121: */
122: public Rectangle2D getBounds2D() {
123: return (Rectangle2D) filterRegion.clone();
124: }
125:
126: public RenderedImage createRendering(RenderContext rc) {
127: //
128: // Get the mask content
129: //
130: Filter maskSrc = getMaskNode().getGraphicsNodeRable(true);
131: PadRable maskPad = new PadRable8Bit(maskSrc, getBounds2D(),
132: PadMode.ZERO_PAD);
133: maskSrc = new FilterAsAlphaRable(maskPad);
134: RenderedImage ri = maskSrc.createRendering(rc);
135: if (ri == null)
136: return null;
137:
138: CachableRed maskCr = RenderedImageCachableRed.wrap(ri);
139:
140: //
141: // Get the masked content
142: //
143: PadRable maskedPad = new PadRable8Bit(getSource(),
144: getBounds2D(), PadMode.ZERO_PAD);
145:
146: ri = maskedPad.createRendering(rc);
147: if (ri == null)
148: return null;
149:
150: CachableRed cr;
151: cr = GraphicsUtil.wrap(ri);
152: cr = GraphicsUtil.convertToLsRGB(cr);
153:
154: // org.apache.batik.test.gvt.ImageDisplay.showImage("Src: ", cr);
155: // org.apache.batik.test.gvt.ImageDisplay.showImage("Mask: ", maskCr);
156:
157: CachableRed ret = new MultiplyAlphaRed(cr, maskCr);
158:
159: // org.apache.batik.test.gvt.ImageDisplay.showImage("Masked: ", ret);
160:
161: // ret = new PadRed(ret, cr.getBounds(), PadMode.ZERO_PAD, rh);
162:
163: return ret;
164: }
165: }
|