1 18 package org.apache.batik.bridge; 19 20 import java.awt.Point ; 21 import java.awt.geom.Rectangle2D ; 22 import java.awt.image.Kernel ; 23 import java.util.Map ; 24 import java.util.StringTokenizer ; 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 ; 34 35 41 public class SVGFeConvolveMatrixElementBridge 42 extends AbstractSVGFilterPrimitiveElementBridge { 43 44 45 48 public SVGFeConvolveMatrixElementBridge() {} 49 50 53 public String getLocalName() { 54 return SVG_FE_CONVOLVE_MATRIX_TAG; 55 } 56 57 75 public Filter createFilter(BridgeContext ctx, 76 Element filterElement, 77 Element filteredElement, 78 GraphicsNode filteredNode, 79 Filter inputFilter, 80 Rectangle2D filterRegion, 81 Map filterMap) { 82 83 int [] orderXY = convertOrder(filterElement); 85 86 float [] kernelMatrix = convertKernelMatrix(filterElement, orderXY); 88 89 float divisor = convertDivisor(filterElement, kernelMatrix); 91 92 float bias = convertNumber(filterElement, SVG_BIAS_ATTRIBUTE, 0); 94 95 int [] targetXY = convertTarget(filterElement, orderXY); 97 98 PadMode padMode = convertEdgeMode(filterElement); 100 101 double [] kernelUnitLength = convertKernelUnitLength(filterElement); 103 104 boolean preserveAlpha = convertPreserveAlpha(filterElement); 106 107 Filter in = getIn(filterElement, 109 filteredElement, 110 filteredNode, 111 inputFilter, 112 filterMap, 113 ctx); 114 if (in == null) { 115 return null; } 117 118 Rectangle2D defaultRegion = in.getBounds2D(); 122 Rectangle2D 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 ConvolveMatrixRable convolve = new ConvolveMatrixRable8Bit(pad); 134 for (int i = 0; i < kernelMatrix.length; i++) { 135 kernelMatrix[i] /= divisor; 136 } 137 convolve.setKernel(new Kernel (orderXY[0], orderXY[1], kernelMatrix)); 138 convolve.setTarget(new Point (targetXY[0], targetXY[1])); 139 convolve.setBias(bias); 140 convolve.setEdgeMode(padMode); 141 convolve.setKernelUnitLength(kernelUnitLength); 142 convolve.setPreserveAlpha(preserveAlpha); 143 144 handleColorInterpolationFilters(convolve, filterElement); 146 147 PadRable filter = new PadRable8Bit 148 (convolve, primitiveRegion, PadMode.ZERO_PAD); 149 150 updateFilterMap(filterElement, filter, filterMap); 152 153 return filter; 154 } 155 156 162 protected static int [] convertOrder(Element filterElement) { 163 String 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 tokens = new StringTokenizer (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 ex) { 177 throw new BridgeException 178 (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED, 179 new Object [] {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 [] {SVG_ORDER_ATTRIBUTE, s}); 185 } 186 return orderXY; 187 } 188 189 196 protected static 197 float [] convertKernelMatrix(Element filterElement, int [] orderXY) { 198 199 String 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 [] {SVG_KERNEL_MATRIX_ATTRIBUTE}); 205 } 206 int size = orderXY[0]*orderXY[1]; 207 float [] kernelMatrix = new float[size]; 208 StringTokenizer tokens = new StringTokenizer (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 ex) { 216 throw new BridgeException 217 (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED, 218 new Object [] {SVG_KERNEL_MATRIX_ATTRIBUTE, s, ex}); 219 } 220 if (i != size) { 221 throw new BridgeException 222 (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED, 223 new Object [] {SVG_KERNEL_MATRIX_ATTRIBUTE, s}); 224 } 225 return kernelMatrix; 226 } 227 228 235 protected static 236 float convertDivisor(Element filterElement, float [] kernelMatrix) { 237 238 String s = filterElement.getAttributeNS(null, SVG_DIVISOR_ATTRIBUTE); 239 if (s.length() == 0) { 240 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 ex) { 250 throw new BridgeException 251 (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED, 252 new Object [] {SVG_DIVISOR_ATTRIBUTE, s, ex}); 253 } 254 } 255 } 256 257 264 protected static 265 int [] convertTarget(Element filterElement, int [] orderXY) { 266 267 int [] targetXY = new int[2]; 268 String 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 [] {SVG_TARGET_X_ATTRIBUTE, s}); 279 } 280 targetXY[0] = v; 281 } catch (NumberFormatException ex) { 282 throw new BridgeException 283 (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED, 284 new Object [] {SVG_TARGET_X_ATTRIBUTE, s, ex}); 285 } 286 } 287 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 [] {SVG_TARGET_Y_ATTRIBUTE, s}); 298 } 299 targetXY[1] = v; 300 } catch (NumberFormatException ex) { 301 throw new BridgeException 302 (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED, 303 new Object [] {SVG_TARGET_Y_ATTRIBUTE, s, ex}); 304 } 305 } 306 return targetXY; 307 } 308 309 315 protected static double [] convertKernelUnitLength(Element filterElement) { 316 String 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 tokens = new StringTokenizer (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 ex) { 331 throw new BridgeException 332 (filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED, 333 new Object [] {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 [] {SVG_KERNEL_UNIT_LENGTH_ATTRIBUTE, s}); 340 } 341 return units; 342 } 343 344 350 protected static PadMode convertEdgeMode(Element filterElement) { 351 String 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 [] {SVG_EDGE_MODE_ATTRIBUTE, s}); 367 } 368 369 375 protected static boolean convertPreserveAlpha(Element filterElement) { 376 String 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 [] {SVG_PRESERVE_ALPHA_ATTRIBUTE, s}); 390 } 391 } 392 | Popular Tags |