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.Map;
023: import java.util.StringTokenizer;
024:
025: import org.apache.batik.ext.awt.image.renderable.Filter;
026: import org.apache.batik.ext.awt.image.renderable.TurbulenceRable;
027: import org.apache.batik.ext.awt.image.renderable.TurbulenceRable8Bit;
028: import org.apache.batik.gvt.GraphicsNode;
029: import org.w3c.dom.Element;
030:
031: /**
032: * Bridge class for the <feTurbulence> element.
033: *
034: * @author <a href="mailto:tkormann@apache.org">Thierry Kormann</a>
035: * @version $Id: SVGFeTurbulenceElementBridge.java 501922 2007-01-31 17:47:47Z dvholten $
036: */
037: public class SVGFeTurbulenceElementBridge extends
038: AbstractSVGFilterPrimitiveElementBridge {
039:
040: /**
041: * Constructs a new bridge for the <feTurbulence> element.
042: */
043: public SVGFeTurbulenceElementBridge() {
044: }
045:
046: /**
047: * Returns 'feTurbulence'.
048: */
049: public String getLocalName() {
050: return SVG_FE_TURBULENCE_TAG;
051: }
052:
053: /**
054: * Creates a <tt>Filter</tt> primitive according to the specified
055: * parameters.
056: *
057: * @param ctx the bridge context to use
058: * @param filterElement the element that defines a filter
059: * @param filteredElement the element that references the filter
060: * @param filteredNode the graphics node to filter
061: *
062: * @param inputFilter the <tt>Filter</tt> that represents the current
063: * filter input if the filter chain.
064: * @param filterRegion the filter area defined for the filter chain
065: * the new node will be part of.
066: * @param filterMap a map where the mediator can map a name to the
067: * <tt>Filter</tt> it creates. Other <tt>FilterBridge</tt>s
068: * can then access a filter node from the filterMap if they
069: * know its name.
070: */
071: public Filter createFilter(BridgeContext ctx,
072: Element filterElement, Element filteredElement,
073: GraphicsNode filteredNode, Filter inputFilter,
074: Rectangle2D filterRegion, Map filterMap) {
075:
076: // 'in' attribute
077: Filter in = getIn(filterElement, filteredElement, filteredNode,
078: inputFilter, filterMap, ctx);
079: if (in == null) {
080: return null; // disable the filter
081: }
082:
083: // default region is the filter chain region
084: Rectangle2D defaultRegion = filterRegion;
085: Rectangle2D primitiveRegion = SVGUtilities
086: .convertFilterPrimitiveRegion(filterElement,
087: filteredElement, filteredNode, defaultRegion,
088: filterRegion, ctx);
089:
090: // 'baseFrequency' attribute - default is [0, 0]
091: float[] baseFrequency = convertBaseFrenquency(filterElement,
092: ctx);
093:
094: // 'numOctaves' attribute - default is 1
095: int numOctaves = convertInteger(filterElement,
096: SVG_NUM_OCTAVES_ATTRIBUTE, 1, ctx);
097:
098: // 'seed' attribute - default is 0
099: int seed = convertInteger(filterElement, SVG_SEED_ATTRIBUTE, 0,
100: ctx);
101:
102: // 'stitchTiles' attribute - default is 'noStitch'
103: boolean stitchTiles = convertStitchTiles(filterElement, ctx);
104:
105: // 'fractalNoise' attribute - default is 'turbulence'
106: boolean isFractalNoise = convertType(filterElement, ctx);
107:
108: // create the filter primitive
109: TurbulenceRable turbulenceRable = new TurbulenceRable8Bit(
110: primitiveRegion);
111:
112: turbulenceRable.setBaseFrequencyX(baseFrequency[0]);
113: turbulenceRable.setBaseFrequencyY(baseFrequency[1]);
114: turbulenceRable.setNumOctaves(numOctaves);
115: turbulenceRable.setSeed(seed);
116: turbulenceRable.setStitched(stitchTiles);
117: turbulenceRable.setFractalNoise(isFractalNoise);
118:
119: // handle the 'color-interpolation-filters' property
120: handleColorInterpolationFilters(turbulenceRable, filterElement);
121:
122: // update the filter Map
123: updateFilterMap(filterElement, turbulenceRable, filterMap);
124:
125: return turbulenceRable;
126: }
127:
128: /**
129: * Converts the 'baseFrequency' attribute of the specified
130: * feTurbulence element.
131: *
132: * @param e the feTurbulence element
133: * @param ctx the BridgeContext to use for error information
134: */
135: protected static float[] convertBaseFrenquency(Element e,
136: BridgeContext ctx) {
137: String s = e.getAttributeNS(null, SVG_BASE_FREQUENCY_ATTRIBUTE);
138: if (s.length() == 0) {
139: return new float[] { 0.001f, 0.001f };
140: }
141: float[] v = new float[2];
142: StringTokenizer tokens = new StringTokenizer(s, " ,");
143: try {
144: v[0] = SVGUtilities.convertSVGNumber(tokens.nextToken());
145: if (tokens.hasMoreTokens()) {
146: v[1] = SVGUtilities
147: .convertSVGNumber(tokens.nextToken());
148: } else {
149: v[1] = v[0];
150: }
151: if (tokens.hasMoreTokens()) {
152: throw new BridgeException(ctx, e,
153: ERR_ATTRIBUTE_VALUE_MALFORMED, new Object[] {
154: SVG_BASE_FREQUENCY_ATTRIBUTE, s });
155: }
156: } catch (NumberFormatException nfEx) {
157: throw new BridgeException(ctx, e, nfEx,
158: ERR_ATTRIBUTE_VALUE_MALFORMED, new Object[] {
159: SVG_BASE_FREQUENCY_ATTRIBUTE, s });
160: }
161: if (v[0] < 0 || v[1] < 0) {
162: throw new BridgeException(ctx, e,
163: ERR_ATTRIBUTE_VALUE_MALFORMED, new Object[] {
164: SVG_BASE_FREQUENCY_ATTRIBUTE, s });
165: }
166: return v;
167: }
168:
169: /**
170: * Converts the 'stitchTiles' attribute of the specified
171: * feTurbulence element.
172: *
173: * @param e the feTurbulence element
174: * @param ctx the BridgeContext to use for error information
175: * @return true if stitchTiles attribute is 'stitch', false otherwise
176: */
177: protected static boolean convertStitchTiles(Element e,
178: BridgeContext ctx) {
179: String s = e.getAttributeNS(null, SVG_STITCH_TILES_ATTRIBUTE);
180: if (s.length() == 0) {
181: return false;
182: }
183: if (SVG_STITCH_VALUE.equals(s)) {
184: return true;
185: }
186: if (SVG_NO_STITCH_VALUE.equals(s)) {
187: return false;
188: }
189: throw new BridgeException(ctx, e,
190: ERR_ATTRIBUTE_VALUE_MALFORMED, new Object[] {
191: SVG_STITCH_TILES_ATTRIBUTE, s });
192: }
193:
194: /**
195: * Converts the 'type' attribute of the specified feTurbulence element.
196: *
197: * @param e the feTurbulence element
198: * @param ctx the BridgeContext to use for error information
199: * @return true if type attribute value is 'fractalNoise', false otherwise
200: */
201: protected static boolean convertType(Element e, BridgeContext ctx) {
202: String s = e.getAttributeNS(null, SVG_TYPE_ATTRIBUTE);
203: if (s.length() == 0) {
204: return false;
205: }
206: if (SVG_FRACTAL_NOISE_VALUE.equals(s)) {
207: return true;
208: }
209: if (SVG_TURBULENCE_VALUE.equals(s)) {
210: return false;
211: }
212: throw new BridgeException(ctx, e,
213: ERR_ATTRIBUTE_VALUE_MALFORMED, new Object[] {
214: SVG_TYPE_ATTRIBUTE, s });
215: }
216: }
|