| /* |
| |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| */ |
| package org.apache.batik.bridge; |
| |
| import java.awt.Color; |
| import java.awt.Paint; |
| import java.awt.geom.AffineTransform; |
| import java.awt.geom.Point2D; |
| import java.awt.geom.Rectangle2D; |
| |
| import org.apache.batik.dom.svg.SVGContext; |
| import org.apache.batik.ext.awt.MultipleGradientPaint; |
| import org.apache.batik.ext.awt.RadialGradientPaint; |
| import org.apache.batik.gvt.GraphicsNode; |
| |
| import org.w3c.dom.Element; |
| |
| /** |
| * Bridge class for the <radialGradient> element. |
| * |
| * @author <a href="mailto:tkormann@apache.org">Thierry Kormann</a> |
| * @version $Id$ |
| */ |
| public class SVGRadialGradientElementBridge |
| extends AbstractSVGGradientElementBridge { |
| |
| |
| /** |
| * Constructs a new SVGRadialGradientElementBridge. |
| */ |
| public SVGRadialGradientElementBridge() {} |
| |
| /** |
| * Returns 'radialGradient'. |
| */ |
| public String getLocalName() { |
| return SVG_RADIAL_GRADIENT_TAG; |
| } |
| |
| /** |
| * Builds a radial gradient according to the specified parameters. |
| * |
| * @param paintElement the element that defines a Paint |
| * @param paintedElement the element referencing the paint |
| * @param paintedNode the graphics node on which the Paint will be applied |
| * @param spreadMethod the spread method |
| * @param colorSpace the color space (sRGB | LinearRGB) |
| * @param transform the gradient transform |
| * @param colors the colors of the gradient |
| * @param offsets the offsets |
| * @param ctx the bridge context to use |
| */ |
| protected |
| Paint buildGradient(Element paintElement, |
| Element paintedElement, |
| GraphicsNode paintedNode, |
| MultipleGradientPaint.CycleMethodEnum spreadMethod, |
| MultipleGradientPaint.ColorSpaceEnum colorSpace, |
| AffineTransform transform, |
| Color [] colors, |
| float [] offsets, |
| BridgeContext ctx) { |
| |
| // 'cx' attribute - default is 50% |
| String cxStr = SVGUtilities.getChainableAttributeNS |
| (paintElement, null, SVG_CX_ATTRIBUTE, ctx); |
| if (cxStr.length() == 0) { |
| cxStr = SVG_RADIAL_GRADIENT_CX_DEFAULT_VALUE; |
| } |
| |
| // 'cy' attribute - default is 50% |
| String cyStr = SVGUtilities.getChainableAttributeNS |
| (paintElement, null, SVG_CY_ATTRIBUTE, ctx); |
| if (cyStr.length() == 0) { |
| cyStr = SVG_RADIAL_GRADIENT_CY_DEFAULT_VALUE; |
| } |
| |
| // 'r' attribute - default is 50% |
| String rStr = SVGUtilities.getChainableAttributeNS |
| (paintElement, null, SVG_R_ATTRIBUTE, ctx); |
| if (rStr.length() == 0) { |
| rStr = SVG_RADIAL_GRADIENT_R_DEFAULT_VALUE; |
| } |
| |
| // 'fx' attribute - default is same as cx |
| String fxStr = SVGUtilities.getChainableAttributeNS |
| (paintElement, null, SVG_FX_ATTRIBUTE, ctx); |
| if (fxStr.length() == 0) { |
| fxStr = cxStr; |
| } |
| |
| // 'fy' attribute - default is same as cy |
| String fyStr = SVGUtilities.getChainableAttributeNS |
| (paintElement, null, SVG_FY_ATTRIBUTE, ctx); |
| if (fyStr.length() == 0) { |
| fyStr = cyStr; |
| } |
| |
| // 'gradientUnits' attribute - default is objectBoundingBox |
| short coordSystemType; |
| String s = SVGUtilities.getChainableAttributeNS |
| (paintElement, null, SVG_GRADIENT_UNITS_ATTRIBUTE, ctx); |
| if (s.length() == 0) { |
| coordSystemType = SVGUtilities.OBJECT_BOUNDING_BOX; |
| } else { |
| coordSystemType = SVGUtilities.parseCoordinateSystem |
| (paintElement, SVG_GRADIENT_UNITS_ATTRIBUTE, s, ctx); |
| } |
| |
| // The last paragraph of section 7.11 in SVG 1.1 states that objects |
| // with zero width or height bounding boxes that use gradients with |
| // gradientUnits="objectBoundingBox" must not use the gradient. |
| SVGContext bridge = BridgeContext.getSVGContext(paintedElement); |
| if (coordSystemType == SVGUtilities.OBJECT_BOUNDING_BOX |
| && bridge instanceof AbstractGraphicsNodeBridge) { |
| // XXX Make this work for non-AbstractGraphicsNodeBridges, like |
| // the various text child bridges. |
| Rectangle2D bbox = bridge.getBBox(); |
| if (bbox != null && (bbox.getWidth() == 0 || bbox.getHeight() == 0)) { |
| return null; |
| } |
| } |
| |
| // additional transform to move to objectBoundingBox coordinate system |
| if (coordSystemType == SVGUtilities.OBJECT_BOUNDING_BOX) { |
| transform = SVGUtilities.toObjectBBox(transform, |
| paintedNode); |
| } |
| UnitProcessor.Context uctx |
| = UnitProcessor.createContext(ctx, paintElement); |
| |
| float r = SVGUtilities.convertLength(rStr, |
| SVG_R_ATTRIBUTE, |
| coordSystemType, |
| uctx); |
| // A value of zero will cause the area to be painted as a single color |
| // using the color and opacity of the last gradient stop. |
| if (r == 0) { |
| return colors[colors.length-1]; |
| } else { |
| Point2D c = SVGUtilities.convertPoint(cxStr, |
| SVG_CX_ATTRIBUTE, |
| cyStr, |
| SVG_CY_ATTRIBUTE, |
| coordSystemType, |
| uctx); |
| |
| Point2D f = SVGUtilities.convertPoint(fxStr, |
| SVG_FX_ATTRIBUTE, |
| fyStr, |
| SVG_FY_ATTRIBUTE, |
| coordSystemType, |
| uctx); |
| |
| // <!> FIXME: colorSpace ignored for radial gradient at this time |
| return new RadialGradientPaint(c, |
| r, |
| f, |
| offsets, |
| colors, |
| spreadMethod, |
| RadialGradientPaint.SRGB, |
| transform); |
| } |
| } |
| } |