1 /* 2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.scenario.effect.impl.state; 27 28 import java.nio.FloatBuffer; 29 import com.sun.javafx.geom.Rectangle; 30 import com.sun.javafx.geom.transform.BaseTransform; 31 import com.sun.javafx.geom.transform.NoninvertibleTransformException; 32 33 public class MotionBlurState extends LinearConvolveKernel { 34 private float radius; 35 private float angle; 36 private FloatBuffer weights; 37 38 public float getRadius() { 39 return radius; 40 } 41 42 public void setRadius(float radius) { 43 if (radius < 0f || radius > 63f) { 44 throw new IllegalArgumentException("Radius must be in the range [1,63]"); 45 } 46 this.radius = radius; 47 } 48 49 public float getAngle() { 50 return angle; 51 } 52 53 public void setAngle(float angle) { 54 this.angle = angle; 55 } 56 57 public int getHPad() { 58 return (int) Math.ceil(Math.abs(Math.cos(angle)) * radius); 59 } 60 61 public int getVPad() { 62 return (int) Math.ceil(Math.abs(Math.sin(angle)) * radius); 63 } 64 65 @Override 66 public int getNumberOfPasses() { 67 return 1; 68 } 69 70 @Override 71 public boolean isNop() { 72 return (radius == 0f); 73 } 74 75 @Override 76 public boolean isNop(int pass) { 77 return (pass > 0 || radius == 0f); 78 } 79 80 @Override 81 public int getKernelSize(int pass) { 82 return ((int) Math.ceil(radius)) * 2 + 1; 83 } 84 85 @Override 86 public final Rectangle getResultBounds(Rectangle srcdimension, int pass) { 87 Rectangle ret = new Rectangle(srcdimension); 88 ret.grow(getHPad(), getVPad()); 89 return ret; 90 } 91 92 @Override 93 public float[] getVector(Rectangle srcnativedimensions, 94 BaseTransform transform, int pass) 95 { 96 // float xoff = (float) (Math.cos(angle) / srcnativedimensions.width); 97 // float yoff = (float) (Math.sin(angle) / srcnativedimensions.height); 98 float ret[] = new float[4]; 99 float cos = (float) Math.cos(angle); 100 float sin = (float) Math.sin(angle); 101 if (!transform.isTranslateOrIdentity()) { 102 ret[0] = cos; 103 ret[1] = sin; 104 try { 105 transform.inverseDeltaTransform(ret, 0, ret, 0, 1); 106 cos = ret[0]; 107 sin = ret[1]; 108 } catch (NoninvertibleTransformException e) { 109 sin = cos = 0f; 110 } 111 } 112 float xoff = cos / srcnativedimensions.width; 113 float yoff = sin / srcnativedimensions.height; 114 int ksize = getScaledKernelSize(pass); 115 int center = ksize / 2; 116 ret[0] = xoff; 117 ret[1] = yoff; 118 ret[2] = -center * xoff; 119 ret[3] = -center * yoff; 120 return ret; 121 } 122 123 @Override 124 public FloatBuffer getWeights(int pass) { 125 int pad = (int) Math.ceil(radius); 126 weights = GaussianBlurState.getGaussianWeights(weights, pad, radius, 0f); 127 return weights; 128 } 129 }