/* * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package javafx.scene.effect; import javafx.beans.property.DoubleProperty; import javafx.beans.property.DoublePropertyBase; import javafx.beans.property.IntegerProperty; import javafx.beans.property.IntegerPropertyBase; import javafx.beans.property.ObjectProperty; import javafx.scene.Node; import com.sun.javafx.util.Utils; import com.sun.javafx.effect.EffectDirtyBits; import com.sun.javafx.geom.BaseBounds; import com.sun.javafx.geom.transform.BaseTransform; import com.sun.javafx.scene.BoundsAccessor; /** * A blur effect using a simple box filter kernel, with separately * configurable sizes in both dimensions, and an iteration parameter * that controls the quality of the resulting blur. * *
* Example: *
* BoxBlur boxBlur = new BoxBlur();
* boxBlur.setWidth(10);
* boxBlur.setHeight(3);
* boxBlur.setIterations(3);
*
* Text text = new Text();
* text.setText("Blurry Text!");
* text.setFill(Color.web("0x3b596d"));
* text.setFont(Font.font(null, FontWeight.BOLD, 50));
* text.setX(10);
* text.setY(50);
* text.setEffect(boxBlur);
*
* * The code above produces the following: *
*
*
*
* Min: 0.0 * Max: 255.0 * Default: 5.0 * Identity: <1.0 ** @defaultValue 5.0 */ private DoubleProperty width; public final void setWidth(double value) { widthProperty().set(value); } public final double getWidth() { return width == null ? 5 : width.get(); } public final DoubleProperty widthProperty() { if (width == null) { width = new DoublePropertyBase(5) { @Override public void invalidated() { markDirty(EffectDirtyBits.EFFECT_DIRTY); effectBoundsChanged(); } @Override public Object getBean() { return BoxBlur.this; } @Override public String getName() { return "width"; } }; } return width; } /** * The vertical dimension of the blur effect. * The color information for a given pixel will be spread across * a Box of the indicated height centered over the pixel. * Values less than or equal to 1 will not spread the color data * beyond the pixel where it originated from and so will have * no effect. *
* Min: 0.0 * Max: 255.0 * Default: 5.0 * Identity: <1.0 ** @defaultValue 5.0 */ private DoubleProperty height; public final void setHeight(double value) { heightProperty().set(value); } public final double getHeight() { return height == null ? 5 : height.get(); } public final DoubleProperty heightProperty() { if (height == null) { height = new DoublePropertyBase(5) { @Override public void invalidated() { markDirty(EffectDirtyBits.EFFECT_DIRTY); effectBoundsChanged(); } @Override public Object getBean() { return BoxBlur.this; } @Override public String getName() { return "height"; } }; } return height; } /** * The number of times to iterate the blur effect to improve its * "quality" or "smoothness". * Iterating the effect 3 times approximates the quality of a * Gaussian Blur to within 3%. *
* Min: 0 * Max: 3 * Default: 1 * Identity: 0 ** @defaultValue 1 */ private IntegerProperty iterations; public final void setIterations(int value) { iterationsProperty().set(value); } public final int getIterations() { return iterations == null ? 1 : iterations.get(); } public final IntegerProperty iterationsProperty() { if (iterations == null) { iterations = new IntegerPropertyBase(1) { @Override public void invalidated() { markDirty(EffectDirtyBits.EFFECT_DIRTY); effectBoundsChanged(); } @Override public Object getBean() { return BoxBlur.this; } @Override public String getName() { return "iterations"; } }; } return iterations; } private int getClampedWidth() { return Utils.clamp(0, (int) getWidth(), 255); } private int getClampedHeight() { return Utils.clamp(0, (int) getHeight(), 255); } private int getClampedIterations() { return Utils.clamp(0, getIterations(), 3); } @Override void impl_update() { Effect localInput = getInput(); if (localInput != null) { localInput.impl_sync(); } com.sun.scenario.effect.BoxBlur peer = (com.sun.scenario.effect.BoxBlur) impl_getImpl(); peer.setInput(localInput == null ? null : localInput.impl_getImpl()); peer.setHorizontalSize(getClampedWidth()); peer.setVerticalSize(getClampedHeight()); peer.setPasses(getClampedIterations()); } /** * @treatAsPrivate implementation detail * @deprecated This is an internal API that is not intended for use and will be removed in the next version */ @Deprecated @Override public BaseBounds impl_getBounds(BaseBounds bounds, BaseTransform tx, Node node, BoundsAccessor boundsAccessor) { bounds = getInputBounds(bounds, BaseTransform.IDENTITY_TRANSFORM, node, boundsAccessor, getInput()); int localIterations = getClampedIterations(); int hgrow = getKernelSize(getClampedWidth(), localIterations); int vgrow = getKernelSize(getClampedHeight(), localIterations); bounds = bounds.deriveWithPadding(hgrow, vgrow, 0); return transformBounds(tx, bounds); } /** * @treatAsPrivate implementation detail * @deprecated This is an internal API that is not intended for use and will be removed in the next version */ @Deprecated @Override public Effect impl_copy() { BoxBlur bb = new BoxBlur(this.getWidth(), this.getHeight(), this.getIterations()); bb.setInput(this.getInput()); return bb; } }