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.bridge;
020:
021: import java.awt.geom.Rectangle2D;
022: import java.util.ArrayList;
023: import java.util.List;
024: import java.util.Map;
025:
026: import org.apache.batik.ext.awt.image.ARGBChannel;
027: import org.apache.batik.ext.awt.image.PadMode;
028: import org.apache.batik.ext.awt.image.renderable.DisplacementMapRable8Bit;
029: import org.apache.batik.ext.awt.image.renderable.Filter;
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.gvt.GraphicsNode;
033: import org.w3c.dom.Element;
034:
035: /**
036: * Bridge class for the <feDisplacementMap> element.
037: *
038: * @author <a href="mailto:tkormann@apache.org">Thierry Kormann</a>
039: * @version $Id: SVGFeDisplacementMapElementBridge.java 475477 2006-11-15 22:44:28Z cam $
040: */
041: public class SVGFeDisplacementMapElementBridge extends
042: AbstractSVGFilterPrimitiveElementBridge {
043:
044: /**
045: * Constructs a new bridge for the <feDisplacementMap> element.
046: */
047: public SVGFeDisplacementMapElementBridge() {
048: }
049:
050: /**
051: * Returns 'feDisplacementMap'.
052: */
053: public String getLocalName() {
054: return SVG_FE_DISPLACEMENT_MAP_TAG;
055: }
056:
057: /**
058: * Creates a <tt>Filter</tt> primitive according to the specified
059: * parameters.
060: *
061: * @param ctx the bridge context to use
062: * @param filterElement the element that defines a filter
063: * @param filteredElement the element that references the filter
064: * @param filteredNode the graphics node to filter
065: *
066: * @param inputFilter the <tt>Filter</tt> that represents the current
067: * filter input if the filter chain.
068: * @param filterRegion the filter area defined for the filter chain
069: * the new node will be part of.
070: * @param filterMap a map where the mediator can map a name to the
071: * <tt>Filter</tt> it creates. Other <tt>FilterBridge</tt>s
072: * can then access a filter node from the filterMap if they
073: * know its name.
074: */
075: public Filter createFilter(BridgeContext ctx,
076: Element filterElement, Element filteredElement,
077: GraphicsNode filteredNode, Filter inputFilter,
078: Rectangle2D filterRegion, Map filterMap) {
079:
080: // 'scale' attribute - default is 0
081: float scale = convertNumber(filterElement, SVG_SCALE_ATTRIBUTE,
082: 0, ctx);
083:
084: // 'xChannelSelector' attribute - default is 'A'
085: ARGBChannel xChannelSelector = convertChannelSelector(
086: filterElement, SVG_X_CHANNEL_SELECTOR_ATTRIBUTE,
087: ARGBChannel.A, ctx);
088:
089: // 'yChannelSelector' attribute - default is 'A'
090: ARGBChannel yChannelSelector = convertChannelSelector(
091: filterElement, SVG_Y_CHANNEL_SELECTOR_ATTRIBUTE,
092: ARGBChannel.A, ctx);
093:
094: // 'in' attribute
095: Filter in = getIn(filterElement, filteredElement, filteredNode,
096: inputFilter, filterMap, ctx);
097: if (in == null) {
098: return null; // disable the filter
099: }
100:
101: // 'in2' attribute - required
102: Filter in2 = getIn2(filterElement, filteredElement,
103: filteredNode, inputFilter, filterMap, ctx);
104: if (in2 == null) {
105: return null; // disable the filter
106: }
107:
108: Rectangle2D defaultRegion;
109: defaultRegion = (Rectangle2D) in.getBounds2D().clone();
110: defaultRegion.add(in2.getBounds2D());
111: // get filter primitive chain region
112: Rectangle2D primitiveRegion = SVGUtilities
113: .convertFilterPrimitiveRegion(filterElement,
114: filteredElement, filteredNode, defaultRegion,
115: filterRegion, ctx);
116:
117: PadRable pad = new PadRable8Bit(in, primitiveRegion,
118: PadMode.ZERO_PAD);
119:
120: // build the displacement map filter
121: List srcs = new ArrayList(2);
122: srcs.add(pad);
123: srcs.add(in2);
124: Filter displacementMap = new DisplacementMapRable8Bit(srcs,
125: scale, xChannelSelector, yChannelSelector);
126:
127: // handle the 'color-interpolation-filters' property
128: handleColorInterpolationFilters(displacementMap, filterElement);
129:
130: PadRable filter = new PadRable8Bit(displacementMap,
131: primitiveRegion, PadMode.ZERO_PAD);
132:
133: // update the filter Map
134: updateFilterMap(filterElement, filter, filterMap);
135:
136: return filter;
137: }
138:
139: /**
140: * Returns the channel for the specified feDisplacementMap filter
141: * primitive attribute, considering the specified attribute name.
142: *
143: * @param filterElement the feDisplacementMap filter primitive element
144: * @param attrName the name of the channel attribute
145: * @param ctx the BridgeContext to use for error information
146: */
147: protected static ARGBChannel convertChannelSelector(
148: Element filterElement, String attrName,
149: ARGBChannel defaultChannel, BridgeContext ctx) {
150:
151: String s = filterElement.getAttributeNS(null, attrName);
152: if (s.length() == 0) {
153: return defaultChannel;
154: }
155: if (SVG_A_VALUE.equals(s)) {
156: return ARGBChannel.A;
157: }
158: if (SVG_R_VALUE.equals(s)) {
159: return ARGBChannel.R;
160: }
161: if (SVG_G_VALUE.equals(s)) {
162: return ARGBChannel.G;
163: }
164: if (SVG_B_VALUE.equals(s)) {
165: return ARGBChannel.B;
166: }
167: throw new BridgeException(ctx, filterElement,
168: ERR_ATTRIBUTE_VALUE_MALFORMED, new Object[] { attrName,
169: s });
170: }
171: }
|