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