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