1 /* 2 * Copyright (c) 2010, 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; 27 28 import javafx.scene.paint.Color; 29 import javafx.scene.paint.CycleMethod; 30 import javafx.scene.paint.LinearGradient; 31 import javafx.scene.paint.Paint; 32 import javafx.scene.paint.RadialGradient; 33 import javafx.scene.paint.Stop; 34 import javafx.scene.text.Font; 35 import com.sun.javafx.css.ParsedValueImpl; 36 import javafx.css.converter.PaintConverter; 37 import javafx.css.converter.StopConverter; 38 import org.junit.Test; 39 import static org.junit.Assert.assertEquals; 40 41 42 public class PaintTypeTest { 43 44 public PaintTypeTest() { 45 } 46 47 final Stop[] stops = new Stop[] { 48 new Stop(0.0f, Color.WHITE), 49 new Stop(1.0f, Color.BLACK) 50 }; 51 52 final Paint[] paints = new Paint[] { 53 Color.rgb(0, 128, 255), 54 new LinearGradient(0.0f, 0.0f, 1.0f, 1.0f, true, CycleMethod.NO_CYCLE, stops), 55 new RadialGradient(225, 0.28, 1f, 1f, 5.0f, false, CycleMethod.NO_CYCLE, stops) 56 }; 57 58 ParsedValue<?,Size> sizeVal(float value) { 59 return new ParsedValueImpl<Size,Size>(new Size(value*100, SizeUnits.PERCENT), null); 60 } 61 62 ParsedValue<ParsedValue[],Stop> stopValue(Stop stop) { 63 ParsedValue<?,Size> offset = sizeVal((float)stop.getOffset()); 64 ParsedValue<Color,Color> color = new ParsedValueImpl<Color,Color>(stop.getColor(), null); 65 ParsedValue[] values = new ParsedValue[] { offset, color }; 66 return new ParsedValueImpl<ParsedValue[],Stop>(values, StopConverter.getInstance()); 67 }; 68 69 ParsedValue<ParsedValue[],Paint> linearGradientValues(LinearGradient lg) { 70 ParsedValue[] values = new ParsedValue[7]; 71 int v = 0; 72 values[v++] = sizeVal((float) lg.getStartX()); 73 values[v++] = sizeVal((float) lg.getStartY()); 74 values[v++] = sizeVal((float) lg.getEndX()); 75 values[v++] = sizeVal((float) lg.getEndY()); 76 values[v++] = new ParsedValueImpl<CycleMethod,CycleMethod>(lg.getCycleMethod(),null); 77 values[v++] = stopValue(stops[0]); 78 values[v++] = stopValue(stops[1]); 79 return new ParsedValueImpl<ParsedValue[],Paint>(values, PaintConverter.LinearGradientConverter.getInstance()); 80 } 81 82 ParsedValue<ParsedValue[],Paint> radialGradientValues(RadialGradient rg) { 83 ParsedValue[] values = new ParsedValue[8]; 84 int v = 0; 85 values[v++] = new ParsedValueImpl<Size,Size>(new Size(rg.getFocusAngle(), SizeUnits.PX), null); 86 values[v++] = new ParsedValueImpl<Size,Size>(new Size(rg.getFocusDistance(), SizeUnits.PX), null); 87 values[v++] = sizeVal((float) rg.getCenterX()); 88 values[v++] = sizeVal((float) rg.getCenterY()); 89 values[v++] = new ParsedValueImpl<Size,Size>(new Size(rg.getRadius(), SizeUnits.PX), null); 90 values[v++] = new ParsedValueImpl<CycleMethod,CycleMethod>(rg.getCycleMethod(),null); 91 values[v++] = stopValue(stops[0]); 92 values[v++] = stopValue(stops[1]); 93 return new ParsedValueImpl<ParsedValue[],Paint>(values, PaintConverter.RadialGradientConverter.getInstance()); 94 } 95 96 final ParsedValue[] paintValues = new ParsedValue[] { 97 new ParsedValueImpl<Paint,Paint>(paints[0], null), 98 linearGradientValues((LinearGradient)paints[1]), 99 radialGradientValues((RadialGradient)paints[2]) 100 }; 101 102 /** 103 * Paint is layered (one value per layer). <paint> [, <paint>]*. 104 * In the convert function, the ParsedValue is a ParsedValue for each layer. 105 * That is, value.getValue() returns a ParsedValue[]. 106 */ 107 ParsedValue<ParsedValue<?,Paint>[],Paint[]> getValue(int nLayers) { 108 ParsedValue<Paint,Paint>[] layers = new ParsedValue[nLayers]; 109 for (int l=0; l<nLayers; l++) { 110 layers[l] = paintValues[l % paintValues.length]; 111 } 112 return new ParsedValueImpl<ParsedValue<?,Paint>[],Paint[]>(layers, PaintConverter.SequenceConverter.getInstance()); 113 } 114 /** 115 * Test of convert method, of class PaintType. 116 */ 117 @Test 118 public void testConvert() { 119 //System.out.println("convert"); 120 int nValues = paints.length; 121 ParsedValue<ParsedValue<?,Paint>[],Paint[]> value = getValue(nValues); 122 Font font = null; 123 Paint[] result = value.convert(font); 124 assertEquals(nValues, result.length); 125 for(int r=0; r<result.length; r++) { 126 Paint expResult = paints[r % paints.length]; 127 assertEquals(expResult, result[r]); 128 } 129 } 130 131 String[] css; 132 133 Paint[][] expResults; 134 135 // values for top, right, bottom, left 136 final String[][][] svals = new String[][][] { 137 { {"#ff0000"} }, 138 { {"#ff0000"}, {"#00ff00"}, {"#0000ff"}, {"#ffffff"} } 139 }; 140 141 public void setup() { 142 css = new String[svals.length]; 143 expResults = new Paint[svals.length][]; 144 for (int i=0; i<svals.length; i++) { 145 StringBuilder sbuf = new StringBuilder(); 146 expResults[i] = new Paint[svals[i].length]; 147 for (int j=0; j<svals[i].length; j++) { 148 for (int k=0; k<svals[i][j].length; k++) { 149 expResults[i][j] = Color.web(svals[i][j][k]); 150 sbuf.append(svals[i][j][k]); 151 if (k+1 < svals[i][j].length) sbuf.append(' '); 152 } 153 154 if (j+1 < svals[i].length) sbuf.append(", "); 155 } 156 css[i] = sbuf.toString(); 157 } 158 } 159 160 @Test 161 public void testPaintTypeWithCSS() { 162 setup(); 163 164 for (int i=0; i<css.length; i++) { 165 166 Stylesheet stylesheet = 167 new CssParser().parse("* { -fx-border-color: " + css[i] + "; }"); 168 169 ParsedValue value = TypeTest.getValueFor(stylesheet, "-fx-border-color"); 170 171 Paint[][] paints = (Paint[][])value.convert(Font.getDefault()); 172 173 //assertEquals(expResults[i].length,paints.length); 174 175 for(int j=0; j<paints.length; j++) { 176 String msg = Integer.toString(i) + "." + Integer.toString(j); 177 assertEquals(msg, expResults[i][j], paints[j][0]); 178 } 179 } 180 181 } 182 183 @Test 184 public void testParseRadialGradient() { 185 186 // <radial-gradient> = radial-gradient( 187 // [ focus-angle <angle>, ]? 188 // [ focus-distance <percentage>, ]? 189 // [ center <point>, ]? 190 // radius <length>, 191 // [ [ repeat | reflect ] ,]? 192 // <color-stop>[, <color-stop>]+ ) 193 ParsedValue value = new CssParser().parseExpr("-fx-background-color", 194 "radial-gradient(focus-angle 90deg, focus-distance 50%, radius 50, red, green, blue)"); 195 RadialGradient result = (RadialGradient)((Paint[])value.convert(null))[0]; 196 RadialGradient expected = new RadialGradient(90, .5, 0, 0, 50, 197 false, CycleMethod.NO_CYCLE, 198 new Stop(0, Color.RED), 199 new Stop(.5, Color.GREEN), 200 new Stop(1.0,Color.BLUE)); 201 assertEquals(expected,result); 202 203 value = new CssParser().parseExpr("-fx-background-color", 204 "radial-gradient(focus-angle 1.5708rad, focus-distance 50%, radius 50, red, green, blue)"); 205 result = (RadialGradient)((Paint[])value.convert(null))[0]; 206 assertEquals(expected,result); 207 208 value = new CssParser().parseExpr("-fx-background-color", 209 "radial-gradient(center 0% 10%, radius 50%, reflect, red, green, blue)"); 210 result = (RadialGradient)((Paint[])value.convert(null))[0]; 211 expected = new RadialGradient(0, 0, 0, .1, .5, 212 true, CycleMethod.REFLECT, 213 new Stop(0, Color.RED), 214 new Stop(.5, Color.GREEN), 215 new Stop(1.0,Color.BLUE)); 216 assertEquals(expected,result); 217 } 218 219 @Test 220 public void testParseLinearGradient() { 221 222 // <linear-gradient> = linear-gradient( 223 // [ [from <point> to <point>] | [ to <side-or-corner> ] ] ,]? [ [ repeat | reflect ] ,]? 224 // <color-stop>[, <color-stop>]+ 225 // ) 226 // 227 ParsedValue value = new CssParser().parseExpr("-fx-background-color", 228 "linear-gradient(to top, red, green, blue)"); 229 LinearGradient result = (LinearGradient)((Paint[])value.convert(null))[0]; 230 LinearGradient expected = new LinearGradient(0, 1, 0, 0, 231 true, CycleMethod.NO_CYCLE, 232 new Stop(0, Color.RED), 233 new Stop(.5, Color.GREEN), 234 new Stop(1.0, Color.BLUE)); 235 assertEquals(expected,result); 236 237 value = new CssParser().parseExpr("-fx-background-color", 238 "linear-gradient(to bottom, red, green, blue)"); 239 result = (LinearGradient)((Paint[])value.convert(null))[0]; 240 expected = new LinearGradient(0, 0, 0, 1, 241 true, CycleMethod.NO_CYCLE, 242 new Stop(0, Color.RED), 243 new Stop(.5, Color.GREEN), 244 new Stop(1.0, Color.BLUE)); 245 assertEquals(expected,result); 246 247 value = new CssParser().parseExpr("-fx-background-color", 248 "linear-gradient(to left, red, green, blue)"); 249 result = (LinearGradient)((Paint[])value.convert(null))[0]; 250 expected = new LinearGradient(1, 0, 0, 0, 251 true, CycleMethod.NO_CYCLE, 252 new Stop(0, Color.RED), 253 new Stop(.5, Color.GREEN), 254 new Stop(1.0, Color.BLUE)); 255 assertEquals(expected,result); 256 257 value = new CssParser().parseExpr("-fx-background-color", 258 "linear-gradient(to right, red, green, blue)"); 259 result = (LinearGradient)((Paint[])value.convert(null))[0]; 260 expected = new LinearGradient(0, 0, 1, 0, 261 true, CycleMethod.NO_CYCLE, 262 new Stop(0, Color.RED), 263 new Stop(.5, Color.GREEN), 264 new Stop(1.0, Color.BLUE)); 265 assertEquals(expected,result); 266 267 value = new CssParser().parseExpr("-fx-background-color", 268 "linear-gradient(to bottom left, red, green, blue)"); 269 result = (LinearGradient)((Paint[])value.convert(null))[0]; 270 expected = new LinearGradient(1, 0, 0, 1, 271 true, CycleMethod.NO_CYCLE, 272 new Stop(0, Color.RED), 273 new Stop(.5, Color.GREEN), 274 new Stop(1.0, Color.BLUE)); 275 assertEquals(expected,result); 276 277 value = new CssParser().parseExpr("-fx-background-color", 278 "linear-gradient(to bottom right, red, green, blue)"); 279 result = (LinearGradient)((Paint[])value.convert(null))[0]; 280 expected = new LinearGradient(0, 0, 1, 1, 281 true, CycleMethod.NO_CYCLE, 282 new Stop(0, Color.RED), 283 new Stop(.5, Color.GREEN), 284 new Stop(1.0, Color.BLUE)); 285 assertEquals(expected,result); 286 287 value = new CssParser().parseExpr("-fx-background-color", 288 "linear-gradient(to top left, red, green, blue)"); 289 result = (LinearGradient)((Paint[])value.convert(null))[0]; 290 expected = new LinearGradient(1, 1, 0, 0, 291 true, CycleMethod.NO_CYCLE, 292 new Stop(0, Color.RED), 293 new Stop(.5, Color.GREEN), 294 new Stop(1.0, Color.BLUE)); 295 assertEquals(expected,result); 296 297 value = new CssParser().parseExpr("-fx-background-color", 298 "linear-gradient(to top right, red, green, blue)"); 299 result = (LinearGradient)((Paint[])value.convert(null))[0]; 300 expected = new LinearGradient(0, 1, 1, 0, 301 true, CycleMethod.NO_CYCLE, 302 new Stop(0, Color.RED), 303 new Stop(.5, Color.GREEN), 304 new Stop(1.0, Color.BLUE)); 305 assertEquals(expected,result); 306 307 value = new CssParser().parseExpr("-fx-background-color", 308 "linear-gradient(from 10% 10% to 90% 90%, reflect, red, green, blue)"); 309 result = (LinearGradient)((Paint[])value.convert(null))[0]; 310 expected = new LinearGradient(.1, .1, .9, .9, 311 true, CycleMethod.REFLECT, 312 new Stop(0, Color.RED), 313 new Stop(.5, Color.GREEN), 314 new Stop(1.0, Color.BLUE)); 315 assertEquals(expected,result); 316 } 317 318 }