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.Color;
022: import java.util.StringTokenizer;
023:
024: import org.apache.batik.ext.awt.image.DistantLight;
025: import org.apache.batik.ext.awt.image.Light;
026: import org.apache.batik.ext.awt.image.PointLight;
027: import org.apache.batik.ext.awt.image.SpotLight;
028: import org.w3c.dom.Element;
029: import org.w3c.dom.Node;
030:
031: /**
032: * Bridge class for the <feDiffuseLighting> element.
033: *
034: * @author <a href="mailto:tkormann@apache.org">Thierry Kormann</a>
035: * @version $Id: AbstractSVGLightingElementBridge.java 501922 2007-01-31 17:47:47Z dvholten $
036: */
037: public abstract class AbstractSVGLightingElementBridge extends
038: AbstractSVGFilterPrimitiveElementBridge {
039:
040: /**
041: * Constructs a new bridge for the lighting filter primitives.
042: */
043: protected AbstractSVGLightingElementBridge() {
044: }
045:
046: /**
047: * Returns the light from the specified lighting filter primitive
048: * element or null if any
049: *
050: * @param filterElement the lighting filter primitive element
051: * @param ctx the bridge context
052: */
053: protected static Light extractLight(Element filterElement,
054: BridgeContext ctx) {
055:
056: Color color = CSSUtilities.convertLightingColor(filterElement,
057: ctx);
058:
059: for (Node n = filterElement.getFirstChild(); n != null; n = n
060: .getNextSibling()) {
061:
062: if (n.getNodeType() != Node.ELEMENT_NODE) {
063: continue;
064: }
065:
066: Element e = (Element) n;
067: Bridge bridge = ctx.getBridge(e);
068: if (bridge == null
069: || !(bridge instanceof AbstractSVGLightElementBridge)) {
070: continue;
071: }
072: return ((AbstractSVGLightElementBridge) bridge)
073: .createLight(ctx, filterElement, e, color);
074: }
075: return null;
076: }
077:
078: /**
079: * Convert the 'kernelUnitLength' attribute of the specified
080: * feDiffuseLighting or feSpecularLighting filter primitive element.
081: *
082: * @param filterElement the filter primitive element
083: * @param ctx the BridgeContext to use for error information
084: */
085: protected static double[] convertKernelUnitLength(
086: Element filterElement, BridgeContext ctx) {
087: String s = filterElement.getAttributeNS(null,
088: SVG_KERNEL_UNIT_LENGTH_ATTRIBUTE);
089: if (s.length() == 0) {
090: return null;
091: }
092: double[] units = new double[2];
093: StringTokenizer tokens = new StringTokenizer(s, " ,");
094: try {
095: units[0] = SVGUtilities
096: .convertSVGNumber(tokens.nextToken());
097: if (tokens.hasMoreTokens()) {
098: units[1] = SVGUtilities.convertSVGNumber(tokens
099: .nextToken());
100: } else {
101: units[1] = units[0];
102: }
103: } catch (NumberFormatException nfEx) {
104: throw new BridgeException(ctx, filterElement, nfEx,
105: ERR_ATTRIBUTE_VALUE_MALFORMED, new Object[] {
106: SVG_KERNEL_UNIT_LENGTH_ATTRIBUTE, s });
107:
108: }
109: if (tokens.hasMoreTokens() || units[0] <= 0 || units[1] <= 0) {
110: throw new BridgeException(ctx, filterElement,
111: ERR_ATTRIBUTE_VALUE_MALFORMED, new Object[] {
112: SVG_KERNEL_UNIT_LENGTH_ATTRIBUTE, s });
113: }
114: return units;
115: }
116:
117: /**
118: * The base bridge class for light element.
119: */
120: protected abstract static class AbstractSVGLightElementBridge
121: extends AnimatableGenericSVGBridge {
122:
123: /**
124: * Creates a <tt>Light</tt> according to the specified parameters.
125: *
126: * @param ctx the bridge context to use
127: * @param filterElement the lighting filter primitive element
128: * @param lightElement the element describing a light
129: * @param color the color of the light
130: */
131: public abstract Light createLight(BridgeContext ctx,
132: Element filterElement, Element lightElement, Color color);
133: }
134:
135: /**
136: * Bridge class for the <feSpotLight> element.
137: */
138: public static class SVGFeSpotLightElementBridge extends
139: AbstractSVGLightElementBridge {
140:
141: /**
142: * Constructs a new bridge for a light element.
143: */
144: public SVGFeSpotLightElementBridge() {
145: }
146:
147: /**
148: * Returns 'feSpotLight'.
149: */
150: public String getLocalName() {
151: return SVG_FE_SPOT_LIGHT_TAG;
152: }
153:
154: /**
155: * Creates a <tt>Light</tt> according to the specified parameters.
156: *
157: * @param ctx the bridge context to use
158: * @param filterElement the lighting filter primitive element
159: * @param lightElement the element describing a light
160: * @param color the color of the light
161: */
162: public Light createLight(BridgeContext ctx,
163: Element filterElement, Element lightElement, Color color) {
164:
165: // 'x' attribute - default is 0
166: double x = convertNumber(lightElement, SVG_X_ATTRIBUTE, 0,
167: ctx);
168:
169: // 'y' attribute - default is 0
170: double y = convertNumber(lightElement, SVG_Y_ATTRIBUTE, 0,
171: ctx);
172:
173: // 'z' attribute - default is 0
174: double z = convertNumber(lightElement, SVG_Z_ATTRIBUTE, 0,
175: ctx);
176:
177: // 'pointsAtX' attribute - default is 0
178: double px = convertNumber(lightElement,
179: SVG_POINTS_AT_X_ATTRIBUTE, 0, ctx);
180:
181: // 'pointsAtY' attribute - default is 0
182: double py = convertNumber(lightElement,
183: SVG_POINTS_AT_Y_ATTRIBUTE, 0, ctx);
184:
185: // 'pointsAtZ' attribute - default is 0
186: double pz = convertNumber(lightElement,
187: SVG_POINTS_AT_Z_ATTRIBUTE, 0, ctx);
188:
189: // 'specularExponent' attribute - default is 1
190: double specularExponent = convertNumber(lightElement,
191: SVG_SPECULAR_EXPONENT_ATTRIBUTE, 1, ctx);
192:
193: // 'limitingConeAngle' attribute - default is 90
194: double limitingConeAngle = convertNumber(lightElement,
195: SVG_LIMITING_CONE_ANGLE_ATTRIBUTE, 90, ctx);
196:
197: return new SpotLight(x, y, z, px, py, pz, specularExponent,
198: limitingConeAngle, color);
199: }
200: }
201:
202: /**
203: * Bridge class for the <feDistantLight> element.
204: */
205: public static class SVGFeDistantLightElementBridge extends
206: AbstractSVGLightElementBridge {
207:
208: /**
209: * Constructs a new bridge for a light element.
210: */
211: public SVGFeDistantLightElementBridge() {
212: }
213:
214: /**
215: * Returns 'feDistantLight'.
216: */
217: public String getLocalName() {
218: return SVG_FE_DISTANT_LIGHT_TAG;
219: }
220:
221: /**
222: * Creates a <tt>Light</tt> according to the specified parameters.
223: *
224: * @param ctx the bridge context to use
225: * @param filterElement the lighting filter primitive element
226: * @param lightElement the element describing a light
227: * @param color the color of the light
228: */
229: public Light createLight(BridgeContext ctx,
230: Element filterElement, Element lightElement, Color color) {
231:
232: // 'azimuth' attribute - default is 0
233: double azimuth = convertNumber(lightElement,
234: SVG_AZIMUTH_ATTRIBUTE, 0, ctx);
235:
236: // 'elevation' attribute - default is 0
237: double elevation = convertNumber(lightElement,
238: SVG_ELEVATION_ATTRIBUTE, 0, ctx);
239:
240: return new DistantLight(azimuth, elevation, color);
241: }
242: }
243:
244: /**
245: * Bridge class for the <fePointLight> element.
246: */
247: public static class SVGFePointLightElementBridge extends
248: AbstractSVGLightElementBridge {
249:
250: /**
251: * Constructs a new bridge for a light element.
252: */
253: public SVGFePointLightElementBridge() {
254: }
255:
256: /**
257: * Returns 'fePointLight'.
258: */
259: public String getLocalName() {
260: return SVG_FE_POINT_LIGHT_TAG;
261: }
262:
263: /**
264: * Creates a <tt>Light</tt> according to the specified parameters.
265: *
266: * @param ctx the bridge context to use
267: * @param filterElement the lighting filter primitive element
268: * @param lightElement the element describing a light
269: * @param color the color of the light
270: */
271: public Light createLight(BridgeContext ctx,
272: Element filterElement, Element lightElement, Color color) {
273:
274: // 'x' attribute - default is 0
275: double x = convertNumber(lightElement, SVG_X_ATTRIBUTE, 0,
276: ctx);
277:
278: // 'y' attribute - default is 0
279: double y = convertNumber(lightElement, SVG_Y_ATTRIBUTE, 0,
280: ctx);
281:
282: // 'z' attribute - default is 0
283: double z = convertNumber(lightElement, SVG_Z_ATTRIBUTE, 0,
284: ctx);
285:
286: return new PointLight(x, y, z, color);
287: }
288: }
289: }
|