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