1 /* 2 * Copyright (c) 2011, 2014, 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.css.converter; 27 28 import javafx.css.Size; 29 import javafx.css.ParsedValue; 30 import javafx.css.StyleConverter; 31 import javafx.scene.effect.BlurType; 32 import javafx.scene.effect.DropShadow; 33 import javafx.scene.effect.Effect; 34 import javafx.scene.effect.InnerShadow; 35 import javafx.scene.paint.Color; 36 import javafx.scene.text.Font; 37 38 import java.util.Map; 39 40 /** 41 * @since 9 42 */ 43 public class EffectConverter extends StyleConverter<ParsedValue[], Effect> { 44 45 // lazy, thread-safe instatiation 46 private static class Holder { 47 static final EffectConverter EFFECT_CONVERTER = 48 new EffectConverter(); 49 static final DropShadowConverter DROP_SHADOW_INSTANCE = 50 new DropShadowConverter(); 51 static final InnerShadowConverter INNER_SHADOW_INSTANCE = 52 new InnerShadowConverter(); 53 } 54 55 public static StyleConverter<ParsedValue[], Effect> getInstance() { 56 return Holder.EFFECT_CONVERTER; 57 } 58 59 @Override 60 public Effect convert(ParsedValue<ParsedValue[], Effect> value, Font font) { 61 throw new IllegalArgumentException("Parsed value is not an Effect"); 62 } 63 64 protected EffectConverter() { 65 super(); 66 } 67 68 @Override 69 public String toString() { 70 return "EffectConverter"; 71 } 72 73 public static final class DropShadowConverter extends EffectConverter { 74 75 public static DropShadowConverter getInstance() { 76 return Holder.DROP_SHADOW_INSTANCE; 77 } 78 79 private DropShadowConverter() { 80 super(); 81 } 82 83 // dropshadow( <blur-type> , <color> , <number> , <number> , <number> , <number> ) 84 // <blur-type> = [ gaussian | one-pass-box | three-pass-box | two-pass-box ] 85 // <color> The shadow Color. 86 // <number> The radius of the shadow blur kernel. In the range 87 // [0.0 ... 127.0], typical value 10. 88 // <number> he spread of the shadow. The spread is the portion of 89 // the radius where the contribution of the source material 90 // will be 100%. The remaining portion of the radius will 91 // have a contribution controlled by the blur kernel. A 92 // spread of 0.0 will result in a distribution of the shadow 93 // determined entirely by the blur algorithm. A spread of 94 // 1.0 will result in a solid growth outward of the source 95 // material opacity to the limit of the radius with a very 96 // sharp cutoff to transparency at the radius. In the range 97 // [0.0 ... 1.0] a value of 0.0 is no spread. 98 // <number> The shadow offset in the x direction, in pixels. 99 // <number> The shadow offset in the y direction, in pixels. 100 @Override 101 public Effect convert(ParsedValue<ParsedValue[], Effect> value, Font font) { 102 103 Effect effect = super.getCachedValue(value); 104 if (effect != null) return effect; 105 106 final ParsedValue[] values = value.getValue(); 107 final BlurType blurType = (BlurType) values[0].convert(font); 108 final Color color = (Color) values[1].convert(font); 109 final Double radius = ((Size) values[2].convert(font)).pixels(font); 110 final Double spread = ((Size) values[3].convert(font)).pixels(font); 111 final Double offsetX = ((Size) values[4].convert(font)).pixels(font); 112 final Double offsetY = ((Size) values[5].convert(font)).pixels(font); 113 DropShadow dropShadow = new DropShadow(); 114 if (blurType != null) { 115 dropShadow.setBlurType(blurType); 116 } 117 if (color != null) { 118 dropShadow.setColor(color); 119 } 120 if (spread != null) { 121 dropShadow.setSpread(spread); 122 } 123 if (radius != null) { 124 dropShadow.setRadius(radius); 125 } 126 if (offsetX != null) { 127 dropShadow.setOffsetX(offsetX); 128 } 129 if (offsetY != null) { 130 dropShadow.setOffsetY(offsetY); 131 } 132 133 super.cacheValue(value, dropShadow); 134 135 return dropShadow; 136 } 137 138 @Override 139 public String toString() { 140 return "DropShadowConverter"; 141 } 142 } 143 144 public static final class InnerShadowConverter extends EffectConverter { 145 146 public static InnerShadowConverter getInstance() { 147 return Holder.INNER_SHADOW_INSTANCE; 148 } 149 150 private InnerShadowConverter() { 151 super(); 152 } 153 154 // innershadow( <blur-type> , <color> , <number> , <number> , <number> , <number> ) 155 // <blur-type> = [ gaussian | one-pass-box | three-pass-box | two-pass-box ] 156 // <color> The shadow Color. 157 // <number> The radius of the shadow blur kernel. In the range 158 // [0.0 ... 127.0], typical value 10. 159 // <number> The choke of the shadow. The choke is the portion of the 160 // radius where the contribution of the source material will 161 // be 100%. The remaining portion of the radius will have a 162 // contribution controlled by the blur kernel. A choke of 0.0 163 // will result in a distribution of the shadow determined 164 // entirely by the blur algorithm. A choke of 1.0 will result 165 // in a solid growth inward of the shadow from the edges to 166 // the limit of the radius with a very sharp cutoff to 167 // transparency inside the radius. In the range [0.0 ... 1.0] 168 // a value of 0.0 is no spread. 169 // <number> The shadow offset in the x direction, in pixels. 170 // <number> The shadow offset in the y direction, in pixels. 171 @Override 172 public Effect convert(ParsedValue<ParsedValue[], Effect> value, Font font) { 173 174 Effect effect = super.getCachedValue(value); 175 if (effect != null) return effect; 176 177 final ParsedValue[] values = value.getValue(); 178 final BlurType blurType = (BlurType) values[0].convert(font); 179 final Color color = (Color) values[1].convert(font); 180 final Double radius = ((Size) values[2].convert(font)).pixels(font); 181 final Double choke = ((Size) values[3].convert(font)).pixels(font); 182 final Double offsetX = ((Size) values[4].convert(font)).pixels(font); 183 final Double offsetY = ((Size) values[5].convert(font)).pixels(font); 184 InnerShadow innerShadow = new InnerShadow(); 185 if (blurType != null) { 186 innerShadow.setBlurType(blurType); 187 } 188 if (color != null) { 189 innerShadow.setColor(color); 190 } 191 if (radius != null) { 192 innerShadow.setRadius(radius); 193 } 194 if (choke != null) { 195 innerShadow.setChoke(choke); 196 } 197 if (offsetX != null) { 198 innerShadow.setOffsetX(offsetX); 199 } 200 if (offsetY != null) { 201 innerShadow.setOffsetY(offsetY); 202 } 203 204 super.cacheValue(value, innerShadow); 205 206 return innerShadow; 207 } 208 209 @Override 210 public String toString() { 211 return "InnerShadowConverter"; 212 } 213 } 214 215 private static Map<ParsedValue<ParsedValue[], Effect>, Effect> cache; 216 217 public static void clearCache() { if (cache != null) cache.clear(); } 218 219 } 220