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