/*****************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved. *
* ------------------------------------------------------------------------- *
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in *
* the LICENSE file. *
*****************************************************************************/
package org.apache.batik.bridge;
import java.awt.Color;
import java.util.StringTokenizer;
import org.apache.batik.ext.awt.image.DistantLight;
import org.apache.batik.ext.awt.image.Light;
import org.apache.batik.ext.awt.image.PointLight;
import org.apache.batik.ext.awt.image.SpotLight;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* Bridge class for the <feDiffuseLighting> element.
*
* @author <a href="mailto:tkormann@apache.org">Thierry Kormann</a>
* @version $Id: AbstractSVGLightingElementBridge.java,v 1.3 2003/04/11 13:54:41 vhardy Exp $
*/
public abstract class AbstractSVGLightingElementBridge
extends AbstractSVGFilterPrimitiveElementBridge {
/**
* Constructs a new bridge for the lighting filter primitives.
*/
protected AbstractSVGLightingElementBridge() {}
/**
* Returns the light from the specified lighting filter primitive
* element or null if any
*
* @param filterElement the lighting filter primitive element
* @param ctx the bridge context
*/
protected static
Light extractLight(Element filterElement, BridgeContext ctx) {
Color color = CSSUtilities.convertLightingColor(filterElement, ctx);
for (Node n = filterElement.getFirstChild();
n != null;
n = n.getNextSibling()) {
if (n.getNodeType() != Node.ELEMENT_NODE) {
continue;
}
Element e = (Element)n;
Bridge bridge = ctx.getBridge(e);
if (bridge == null ||
!(bridge instanceof AbstractSVGLightElementBridge)) {
continue;
}
return ((AbstractSVGLightElementBridge)bridge).createLight
(ctx, filterElement, e, color);
}
return null;
}
/**
* Convert the 'kernelUnitLength' attribute of the specified
* feDiffuseLighting or feSpecularLighting filter primitive element.
*
* @param filterElement the filter primitive element
*/
protected static double [] convertKernelUnitLength(Element filterElement) {
String s = filterElement.getAttributeNS
(null, SVG_KERNEL_UNIT_LENGTH_ATTRIBUTE);
if (s.length() == 0) {
return null;
}
double [] units = new double[2];
StringTokenizer tokens = new StringTokenizer(s, " ,");
try {
units[0] = SVGUtilities.convertSVGNumber(tokens.nextToken());
if (tokens.hasMoreTokens()) {
units[1] = SVGUtilities.convertSVGNumber(tokens.nextToken());
} else {
units[1] = units[0];
}
} catch (NumberFormatException ex) {
throw new BridgeException
(filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_KERNEL_UNIT_LENGTH_ATTRIBUTE, s});
}
if (tokens.hasMoreTokens() || units[0] <= 0 || units[1] <= 0) {
throw new BridgeException
(filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_KERNEL_UNIT_LENGTH_ATTRIBUTE, s});
}
return units;
}
/**
* The base bridge class for light element.
*/
protected static abstract class AbstractSVGLightElementBridge
extends AbstractSVGBridge {
/**
* Creates a <tt>Light</tt> according to the specified parameters.
*
* @param ctx the bridge context to use
* @param filterElement the lighting filter primitive element
* @param lightElement the element describing a light
* @param color the color of the light
*/
public abstract Light createLight(BridgeContext ctx,
Element filterElement,
Element lightElement,
Color color);
}
/**
* Bridge class for the <feSpotLight> element.
*/
public static class SVGFeSpotLightElementBridge
extends AbstractSVGLightElementBridge {
/**
* Constructs a new bridge for a light element.
*/
public SVGFeSpotLightElementBridge() {}
/**
* Returns 'feSpotLight'.
*/
public String getLocalName() {
return SVG_FE_SPOT_LIGHT_TAG;
}
/**
* Creates a <tt>Light</tt> according to the specified parameters.
*
* @param ctx the bridge context to use
* @param filterElement the lighting filter primitive element
* @param lightElement the element describing a light
* @param color the color of the light
*/
public Light createLight(BridgeContext ctx,
Element filterElement,
Element lightElement,
Color color) {
// 'x' attribute - default is 0
double x = convertNumber(lightElement, SVG_X_ATTRIBUTE, 0);
// 'y' attribute - default is 0
double y = convertNumber(lightElement, SVG_Y_ATTRIBUTE, 0);
// 'z' attribute - default is 0
double z = convertNumber(lightElement, SVG_Z_ATTRIBUTE, 0);
// 'pointsAtX' attribute - default is 0
double px
= convertNumber(lightElement, SVG_POINTS_AT_X_ATTRIBUTE, 0);
// 'pointsAtY' attribute - default is 0
double py
= convertNumber(lightElement, SVG_POINTS_AT_Y_ATTRIBUTE, 0);
// 'pointsAtZ' attribute - default is 0
double pz
= convertNumber(lightElement, SVG_POINTS_AT_Z_ATTRIBUTE, 0);
// 'specularExponent' attribute - default is 1
double specularExponent = convertNumber
(lightElement, SVG_SPECULAR_EXPONENT_ATTRIBUTE, 1);
// 'limitingConeAngle' attribute - default is 90
double limitingConeAngle = convertNumber
(lightElement, SVG_LIMITING_CONE_ANGLE_ATTRIBUTE, 90);
return new SpotLight(x, y, z,
px, py, pz,
specularExponent,
limitingConeAngle,
color);
}
}
/**
* Bridge class for the <feDistantLight> element.
*/
public static class SVGFeDistantLightElementBridge
extends AbstractSVGLightElementBridge {
/**
* Constructs a new bridge for a light element.
*/
public SVGFeDistantLightElementBridge() {}
/**
* Returns 'feDistantLight'.
*/
public String getLocalName() {
return SVG_FE_DISTANT_LIGHT_TAG;
}
/**
* Creates a <tt>Light</tt> according to the specified parameters.
*
* @param ctx the bridge context to use
* @param filterElement the lighting filter primitive element
* @param lightElement the element describing a light
* @param color the color of the light
*/
public Light createLight(BridgeContext ctx,
Element filterElement,
Element lightElement,
Color color) {
// 'azimuth' attribute - default is 0
double azimuth
= convertNumber(lightElement, SVG_AZIMUTH_ATTRIBUTE, 0);
// 'elevation' attribute - default is 0
double elevation
= convertNumber(lightElement, SVG_ELEVATION_ATTRIBUTE, 0);
return new DistantLight(azimuth, elevation, color);
}
}
/**
* Bridge class for the <fePointLight> element.
*/
public static class SVGFePointLightElementBridge
extends AbstractSVGLightElementBridge {
/**
* Constructs a new bridge for a light element.
*/
public SVGFePointLightElementBridge() {}
/**
* Returns 'fePointLight'.
*/
public String getLocalName() {
return SVG_FE_POINT_LIGHT_TAG;
}
/**
* Creates a <tt>Light</tt> according to the specified parameters.
*
* @param ctx the bridge context to use
* @param filterElement the lighting filter primitive element
* @param lightElement the element describing a light
* @param color the color of the light
*/
public Light createLight(BridgeContext ctx,
Element filterElement,
Element lightElement,
Color color) {
// 'x' attribute - default is 0
double x = convertNumber(lightElement, SVG_X_ATTRIBUTE, 0);
// 'y' attribute - default is 0
double y = convertNumber(lightElement, SVG_Y_ATTRIBUTE, 0);
// 'z' attribute - default is 0
double z = convertNumber(lightElement, SVG_Z_ATTRIBUTE, 0);
return new PointLight(x, y, z, color);
}
}
}