1 /*
   2  * Copyright (c) 2010, 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 javafx.scene.effect;
  27 
  28 import javafx.beans.property.DoubleProperty;
  29 import javafx.beans.property.DoublePropertyBase;
  30 import javafx.beans.property.ObjectProperty;
  31 import javafx.scene.Node;
  32 
  33 import com.sun.javafx.util.Utils;
  34 import com.sun.javafx.effect.EffectDirtyBits;
  35 import com.sun.javafx.geom.BaseBounds;
  36 import com.sun.javafx.geom.transform.BaseTransform;
  37 import com.sun.javafx.scene.BoundsAccessor;
  38 
  39 
  40 /**
  41  * A blur effect using a Gaussian convolution kernel, with a configurable
  42  * radius.
  43  *
  44  * <p>
  45  * Example:
  46  * <pre><code>
  47  * Text text = new Text();
  48  * text.setText("Blurry Text!");
  49  * text.setFill(Color.web("0x3b596d"));
  50  * text.setFont(Font.font(null, FontWeight.BOLD, 50));
  51  * text.setX(10);
  52  * text.setY(50);
  53  *
  54  * text.setEffect(new GaussianBlur());
  55  * </pre></code>
  56  * <p>
  57  * The code above produces the following:
  58  * </p>
  59  * <p>
  60  * <img src="doc-files/gaussianblur.png"/>
  61  * </p>
  62  * @since JavaFX 2.0
  63  */
  64 public class GaussianBlur extends Effect {
  65     /**
  66      * Creates a new instance of GaussianBlur with default parameters.
  67      */
  68     public GaussianBlur() {}
  69 
  70     /**
  71      * Creates a new instance of GaussianBlur with the specified radius.
  72      * @param radius the radius of the blur kernel
  73      * @since JavaFX 2.1
  74      */
  75     public GaussianBlur(double radius) {
  76         setRadius(radius);
  77     }
  78 
  79     @Override
  80     com.sun.scenario.effect.GaussianBlur impl_createImpl() {
  81         return new com.sun.scenario.effect.GaussianBlur();
  82     };
  83     /**
  84      * The input for this {@code Effect}.
  85      * If set to {@code null}, or left unspecified, a graphical image of
  86      * the {@code Node} to which the {@code Effect} is attached will be
  87      * used as the input.
  88      * @defaultValue null
  89      */
  90     private ObjectProperty<Effect> input;
  91 
  92 
  93     public final void setInput(Effect value) {
  94         inputProperty().set(value);
  95     }
  96 
  97     public final Effect getInput() {
  98         return input == null ? null : input.get();
  99     }
 100 
 101     public final ObjectProperty<Effect> inputProperty() {
 102         if (input == null) {
 103             input = new EffectInputProperty("input");
 104         }
 105         return input;
 106     }
 107 
 108     @Override
 109     boolean impl_checkChainContains(Effect e) {
 110         Effect localInput = getInput();
 111         if (localInput == null)
 112             return false;
 113         if (localInput == e)
 114             return true;
 115         return localInput.impl_checkChainContains(e);
 116     }
 117 
 118     /**
 119      * The radius of the blur kernel.
 120      * <pre>
 121      *       Min:  0.0
 122      *       Max: 63.0
 123      *   Default: 10.0
 124      *  Identity:  0.0
 125      * </pre>
 126      * @defaultValue 10.0
 127      */
 128     private DoubleProperty radius;
 129 
 130 
 131     public final void setRadius(double value) {
 132         radiusProperty().set(value);
 133     }
 134 
 135     public final double getRadius() {
 136         return radius == null ? 10 : radius.get();
 137     }
 138 
 139     public final DoubleProperty radiusProperty() {
 140         if (radius == null) {
 141             radius = new DoublePropertyBase(10) {
 142 
 143                 @Override
 144                 public void invalidated() {
 145                     markDirty(EffectDirtyBits.EFFECT_DIRTY);
 146                     effectBoundsChanged();
 147                 }
 148 
 149                 @Override
 150                 public Object getBean() {
 151                     return GaussianBlur.this;
 152                 }
 153 
 154                 @Override
 155                 public String getName() {
 156                     return "radius";
 157                 }
 158             };
 159         }
 160         return radius;
 161     }
 162 
 163     private float getClampedRadius() {
 164         return (float) Utils.clamp(0, getRadius(), 63);
 165     }
 166 
 167     @Override
 168     void impl_update() {
 169         Effect localInput = getInput();
 170         if (localInput != null) {
 171             localInput.impl_sync();
 172         }
 173 
 174         com.sun.scenario.effect.GaussianBlur peer =
 175                 (com.sun.scenario.effect.GaussianBlur) impl_getImpl();
 176         peer.setRadius(getClampedRadius());
 177         peer.setInput(localInput == null ? null : localInput.impl_getImpl());
 178     }
 179 
 180     /**
 181      * @treatAsPrivate implementation detail
 182      * @deprecated This is an internal API that is not intended for use and will be removed in the next version
 183      */
 184     @Deprecated
 185     @Override
 186     public BaseBounds impl_getBounds(BaseBounds bounds,
 187                                      BaseTransform tx,
 188                                      Node node,
 189                                      BoundsAccessor boundsAccessor) {
 190         bounds = getInputBounds(bounds,
 191                                 BaseTransform.IDENTITY_TRANSFORM,
 192                                 node, boundsAccessor,
 193                                 getInput());
 194         float r = getClampedRadius();
 195         bounds = bounds.deriveWithPadding(r, r, 0);
 196         return transformBounds(tx, bounds);
 197     }
 198 
 199     /**
 200      * @treatAsPrivate implementation detail
 201      * @deprecated This is an internal API that is not intended for use and will be removed in the next version
 202      */
 203     @Deprecated
 204     @Override
 205     public Effect impl_copy() {
 206         return new GaussianBlur(this.getRadius());
 207     }
 208 }