KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > bridge > SVGFeConvolveMatrixElementBridge


1 /*
2
3    Copyright 2001-2003 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17  */

18 package org.apache.batik.bridge;
19
20 import java.awt.Point JavaDoc;
21 import java.awt.geom.Rectangle2D JavaDoc;
22 import java.awt.image.Kernel JavaDoc;
23 import java.util.Map JavaDoc;
24 import java.util.StringTokenizer JavaDoc;
25
26 import org.apache.batik.ext.awt.image.PadMode;
27 import org.apache.batik.ext.awt.image.renderable.ConvolveMatrixRable;
28 import org.apache.batik.ext.awt.image.renderable.ConvolveMatrixRable8Bit;
29 import org.apache.batik.ext.awt.image.renderable.Filter;
30 import org.apache.batik.ext.awt.image.renderable.PadRable;
31 import org.apache.batik.ext.awt.image.renderable.PadRable8Bit;
32 import org.apache.batik.gvt.GraphicsNode;
33 import org.w3c.dom.Element JavaDoc;
34
35 /**
36  * Bridge class for the <feConvolveMatrix> element.
37  *
38  * @author <a HREF="mailto:tkormann@apache.org">Thierry Kormann</a>
39  * @version $Id: SVGFeConvolveMatrixElementBridge.java,v 1.15 2004/08/18 07:12:33 vhardy Exp $
40  */

41 public class SVGFeConvolveMatrixElementBridge
42     extends AbstractSVGFilterPrimitiveElementBridge {
43
44
45     /**
46      * Constructs a new bridge for the &lt;feConvolveMatrix> element.
47      */

48     public SVGFeConvolveMatrixElementBridge() {}
49
50     /**
51      * Returns 'feConvolveMatrix'.
52      */

53     public String JavaDoc getLocalName() {
54         return SVG_FE_CONVOLVE_MATRIX_TAG;
55     }
56
57     /**
58      * Creates a <tt>Filter</tt> primitive according to the specified
59      * parameters.
60      *
61      * @param ctx the bridge context to use
62      * @param filterElement the element that defines a filter
63      * @param filteredElement the element that references the filter
64      * @param filteredNode the graphics node to filter
65      *
66      * @param inputFilter the <tt>Filter</tt> that represents the current
67      * filter input if the filter chain.
68      * @param filterRegion the filter area defined for the filter chain
69      * the new node will be part of.
70      * @param filterMap a map where the mediator can map a name to the
71      * <tt>Filter</tt> it creates. Other <tt>FilterBridge</tt>s
72      * can then access a filter node from the filterMap if they
73      * know its name.
74      */

75     public Filter createFilter(BridgeContext ctx,
76                                Element JavaDoc filterElement,
77                                Element JavaDoc filteredElement,
78                                GraphicsNode filteredNode,
79                                Filter inputFilter,
80                                Rectangle2D JavaDoc filterRegion,
81                                Map JavaDoc filterMap) {
82
83         // 'order' attribute - default is [3, 3]
84
int [] orderXY = convertOrder(filterElement);
85
86         // 'kernelMatrix' attribute - required
87
float [] kernelMatrix = convertKernelMatrix(filterElement, orderXY);
88
89         // 'divisor' attribute - default is kernel matrix sum or 1 if sum is 0
90
float divisor = convertDivisor(filterElement, kernelMatrix);
91
92         // 'bias' attribute - default is 0
93
float bias = convertNumber(filterElement, SVG_BIAS_ATTRIBUTE, 0);
94
95         // 'targetX' and 'targetY' attribute
96
int [] targetXY = convertTarget(filterElement, orderXY);
97
98         // 'edgeMode' attribute - default is 'duplicate'
99
PadMode padMode = convertEdgeMode(filterElement);
100
101         // 'kernelUnitLength' attribute
102
double [] kernelUnitLength = convertKernelUnitLength(filterElement);
103
104         // 'preserveAlpha' attribute - default is 'false'
105
boolean preserveAlpha = convertPreserveAlpha(filterElement);
106
107         // 'in' attribute
108
Filter in = getIn(filterElement,
109                           filteredElement,
110                           filteredNode,
111                           inputFilter,
112                           filterMap,
113                           ctx);
114         if (in == null) {
115             return null; // disable the filter
116
}
117
118         // Default region is the size of in (if in is SourceGraphic or
119
// SourceAlpha it will already include a pad/crop to the
120
// proper filter region size).
121
Rectangle2D JavaDoc defaultRegion = in.getBounds2D();
122         Rectangle2D JavaDoc primitiveRegion
123             = SVGUtilities.convertFilterPrimitiveRegion(filterElement,
124                                                         filteredElement,
125                                                         filteredNode,
126                                                         defaultRegion,
127                                                         filterRegion,
128                                                         ctx);
129
130         PadRable pad = new PadRable8Bit(in, primitiveRegion, PadMode.ZERO_PAD);
131
132         // build the convolve filter
133
ConvolveMatrixRable convolve = new ConvolveMatrixRable8Bit(pad);
134         for (int i = 0; i < kernelMatrix.length; i++) {
135             kernelMatrix[i] /= divisor;
136         }
137         convolve.setKernel(new Kernel JavaDoc(orderXY[0], orderXY[1], kernelMatrix));
138         convolve.setTarget(new Point JavaDoc(targetXY[0], targetXY[1]));
139         convolve.setBias(bias);
140         convolve.setEdgeMode(padMode);
141         convolve.setKernelUnitLength(kernelUnitLength);
142         convolve.setPreserveAlpha(preserveAlpha);
143
144         // handle the 'color-interpolation-filters' property
145
handleColorInterpolationFilters(convolve, filterElement);
146
147         PadRable filter = new PadRable8Bit
148             (convolve, primitiveRegion, PadMode.ZERO_PAD);
149
150         // update the filter Map
151
updateFilterMap(filterElement, filter, filterMap);
152
153         return filter;
154     }
155
156     /**
157      * Convert the 'order' attribute of the specified feConvolveMatrix
158      * filter primitive element.
159      *
160      * @param filterElement the feConvolveMatrix filter primitive element
161      */

162     protected static int [] convertOrder(Element JavaDoc filterElement) {
163         String JavaDoc s = filterElement.getAttributeNS(null, SVG_ORDER_ATTRIBUTE);
164         if (s.length() == 0) {
165             return new int[] {3, 3};
166         }
167         int [] orderXY = new int[2];
168         StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(s, " ,");
169         try {
170             orderXY[0] = SVGUtilities.convertSVGInteger(tokens.nextToken());
171             if (tokens.hasMoreTokens()) {
172                 orderXY[1] = SVGUtilities.convertSVGInteger(tokens.nextToken());
173             } else {
174                 orderXY[1] = orderXY[0];
175             }
176         } catch (NumberFormatException JavaDoc ex) {
177             throw new BridgeException
178                 (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
179                  new Object JavaDoc[] {SVG_ORDER_ATTRIBUTE, s, ex});
180         }
181         if (tokens.hasMoreTokens() || orderXY[0] <= 0 || orderXY[1] <= 0) {
182             throw new BridgeException
183                 (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
184                  new Object JavaDoc[] {SVG_ORDER_ATTRIBUTE, s});
185         }
186         return orderXY;
187     }
188
189     /**
190      * Convert the 'kernelMatrix' attribute of the specified feConvolveMatrix
191      * filter primitive element.
192      *
193      * @param filterElement the feConvolveMatrix filter primitive element
194      * @param orderXY the value of the 'order' attribute
195      */

196     protected static
197         float [] convertKernelMatrix(Element JavaDoc filterElement, int [] orderXY) {
198
199         String JavaDoc s =
200             filterElement.getAttributeNS(null, SVG_KERNEL_MATRIX_ATTRIBUTE);
201         if (s.length() == 0) {
202             throw new BridgeException
203                 (filterElement, ERR_ATTRIBUTE_MISSING,
204                  new Object JavaDoc[] {SVG_KERNEL_MATRIX_ATTRIBUTE});
205         }
206         int size = orderXY[0]*orderXY[1];
207         float [] kernelMatrix = new float[size];
208         StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(s, " ,");
209         int i = 0;
210         try {
211             while (tokens.hasMoreTokens() && i < size) {
212                 kernelMatrix[i++]
213                     = SVGUtilities.convertSVGNumber(tokens.nextToken());
214             }
215         } catch (NumberFormatException JavaDoc ex) {
216             throw new BridgeException
217                 (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
218                  new Object JavaDoc[] {SVG_KERNEL_MATRIX_ATTRIBUTE, s, ex});
219         }
220         if (i != size) {
221             throw new BridgeException
222                 (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
223                  new Object JavaDoc[] {SVG_KERNEL_MATRIX_ATTRIBUTE, s});
224         }
225         return kernelMatrix;
226     }
227
228     /**
229      * Convert the 'divisor' attribute of the specified feConvolveMatrix
230      * filter primitive element.
231      *
232      * @param filterElement the feConvolveMatrix filter primitive element
233      * @param kernelMatrix the value of the 'kernelMatrix' attribute
234      */

235     protected static
236         float convertDivisor(Element JavaDoc filterElement, float [] kernelMatrix) {
237
238         String JavaDoc s = filterElement.getAttributeNS(null, SVG_DIVISOR_ATTRIBUTE);
239         if (s.length() == 0) {
240             // default is sum of kernel values (if sum is zero then 1.0)
241
float sum = 0;
242             for (int i=0; i < kernelMatrix.length; ++i) {
243                 sum += kernelMatrix[i];
244             }
245             return (sum == 0) ? 1f : sum;
246         } else {
247             try {
248                 return SVGUtilities.convertSVGNumber(s);
249             } catch (NumberFormatException JavaDoc ex) {
250                 throw new BridgeException
251                     (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
252                      new Object JavaDoc[] {SVG_DIVISOR_ATTRIBUTE, s, ex});
253             }
254         }
255     }
256
257     /**
258      * Convert the 'targetX' and 'targetY' attributes of the specified
259      * feConvolveMatrix filter primitive element.
260      *
261      * @param filterElement the feConvolveMatrix filter primitive element
262      * @param orderXY the value of the 'order' attribute
263      */

264     protected static
265         int [] convertTarget(Element JavaDoc filterElement, int [] orderXY) {
266
267         int [] targetXY = new int[2];
268         // 'targetX' attribute - default is floor(orderX / 2)
269
String JavaDoc s = filterElement.getAttributeNS(null, SVG_TARGET_X_ATTRIBUTE);
270         if (s.length() == 0) {
271             targetXY[0] = orderXY[0] / 2;
272         } else {
273             try {
274                 int v = SVGUtilities.convertSVGInteger(s);
275                 if (v < 0 || v >= orderXY[0]) {
276                     throw new BridgeException
277                         (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
278                          new Object JavaDoc[] {SVG_TARGET_X_ATTRIBUTE, s});
279                 }
280                 targetXY[0] = v;
281             } catch (NumberFormatException JavaDoc ex) {
282                 throw new BridgeException
283                     (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
284                      new Object JavaDoc[] {SVG_TARGET_X_ATTRIBUTE, s, ex});
285             }
286         }
287         // 'targetY' attribute - default is floor(orderY / 2)
288
s = filterElement.getAttributeNS(null, SVG_TARGET_Y_ATTRIBUTE);
289         if (s.length() == 0) {
290             targetXY[1] = orderXY[1] / 2;
291         } else {
292             try {
293                 int v = SVGUtilities.convertSVGInteger(s);
294                 if (v < 0 || v >= orderXY[1]) {
295                     throw new BridgeException
296                         (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
297                          new Object JavaDoc[] {SVG_TARGET_Y_ATTRIBUTE, s});
298                 }
299                 targetXY[1] = v;
300             } catch (NumberFormatException JavaDoc ex) {
301                 throw new BridgeException
302                     (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
303                      new Object JavaDoc[] {SVG_TARGET_Y_ATTRIBUTE, s, ex});
304             }
305         }
306         return targetXY;
307     }
308
309     /**
310      * Convert the 'kernelUnitLength' attribute of the specified
311      * feConvolveMatrix filter primitive element.
312      *
313      * @param filterElement the feConvolveMatrix filter primitive element
314      */

315     protected static double [] convertKernelUnitLength(Element JavaDoc filterElement) {
316         String JavaDoc s = filterElement.getAttributeNS
317             (null, SVG_KERNEL_UNIT_LENGTH_ATTRIBUTE);
318         if (s.length() == 0) {
319             return null;
320         }
321         double [] units = new double[2];
322         StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(s, " ,");
323         try {
324             units[0] = SVGUtilities.convertSVGNumber(tokens.nextToken());
325             if (tokens.hasMoreTokens()) {
326                 units[1] = SVGUtilities.convertSVGNumber(tokens.nextToken());
327             } else {
328                 units[1] = units[0];
329             }
330         } catch (NumberFormatException JavaDoc ex) {
331             throw new BridgeException
332                 (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
333                  new Object JavaDoc[] {SVG_KERNEL_UNIT_LENGTH_ATTRIBUTE, s});
334
335         }
336         if (tokens.hasMoreTokens() || units[0] <= 0 || units[1] <= 0) {
337             throw new BridgeException
338                 (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
339                  new Object JavaDoc[] {SVG_KERNEL_UNIT_LENGTH_ATTRIBUTE, s});
340         }
341         return units;
342     }
343
344     /**
345      * Convert the 'edgeMode' attribute of the specified feConvolveMatrix
346      * filter primitive element.
347      *
348      * @param filterElement the feConvolveMatrix filter primitive element
349      */

350     protected static PadMode convertEdgeMode(Element JavaDoc filterElement) {
351         String JavaDoc s = filterElement.getAttributeNS(null, SVG_EDGE_MODE_ATTRIBUTE);
352         if (s.length() == 0) {
353             return PadMode.REPLICATE;
354         }
355         if (SVG_DUPLICATE_VALUE.equals(s)) {
356             return PadMode.REPLICATE;
357         }
358         if (SVG_WRAP_VALUE.equals(s)) {
359             return PadMode.WRAP;
360         }
361         if (SVG_NONE_VALUE.equals(s)) {
362             return PadMode.ZERO_PAD;
363         }
364         throw new BridgeException
365             (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
366              new Object JavaDoc[] {SVG_EDGE_MODE_ATTRIBUTE, s});
367     }
368
369     /**
370      * Convert the 'preserveAlpha' attribute of the specified feConvolveMatrix
371      * filter primitive element.
372      *
373      * @param filterElement the feConvolveMatrix filter primitive element
374      */

375     protected static boolean convertPreserveAlpha(Element JavaDoc filterElement) {
376         String JavaDoc s
377             = filterElement.getAttributeNS(null, SVG_PRESERVE_ALPHA_ATTRIBUTE);
378         if (s.length() == 0) {
379             return false;
380         }
381         if (SVG_TRUE_VALUE.equals(s)) {
382             return true;
383         }
384         if (SVG_FALSE_VALUE.equals(s)) {
385             return false;
386         }
387         throw new BridgeException
388             (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
389              new Object JavaDoc[] {SVG_PRESERVE_ALPHA_ATTRIBUTE, s});
390     }
391 }
392
Popular Tags