Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. Oracle designates this 008 * particular file as subject to the "Classpath" exception as provided 009 * by Oracle in the LICENSE file that accompanied this code. 010 * 011 * This code is distributed in the hope that it will be useful, but WITHOUT 012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * version 2 for more details (a copy is included in the LICENSE file that 015 * accompanied this code). 016 * 017 * You should have received a copy of the GNU General Public License version 018 * 2 along with this work; if not, write to the Free Software Foundation, 019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 020 * 021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 022 * or visit www.oracle.com if you need additional information or have any 023 * questions. 024 */ 025 026package javafx.scene.layout; 027 028/** 029 * Defines the radii of each of the four corners of a BorderStroke. The 030 * CornerRadii class is immutable and therefore can be reused on multiple 031 * BorderStrokes. This class defines 8 different values, corresponding 032 * to the horizontal and vertical components of 4 quarter ellipses, which 033 * in turn define the curvature of the corners of the BorderStroke. 034 * 035 * TODO insert picture 036 */ 037public class CornerRadii { 038 /** 039 * A CornerRadii which is entirely empty, indicating squared corners. 040 * This is the default value for a BorderStroke's radii. 041 */ 042 public static final CornerRadii EMPTY = new CornerRadii( 043 0, 0, 0, 0, 0, 0, 0, 0, 044 false, false, false, false, false, false, false, false 045 ); 046 047 /** 048 * The length of the horizontal radii of the top-left corner. 049 */ 050 public final double getTopLeftHorizontalRadius() { return topLeftHorizontalRadius; } 051 private double topLeftHorizontalRadius; 052 053 /** 054 * The length of the vertical radii of the top-left corner. 055 */ 056 public final double getTopLeftVerticalRadius() { return topLeftVerticalRadius; } 057 private double topLeftVerticalRadius; 058 059 /** 060 * The length of the vertical radii of the top-right corner. 061 */ 062 public final double getTopRightVerticalRadius() { return topRightVerticalRadius; } 063 private double topRightVerticalRadius; 064 065 /** 066 * The length of the horizontal radii of the top-right corner. 067 */ 068 public final double getTopRightHorizontalRadius() { return topRightHorizontalRadius; } 069 private double topRightHorizontalRadius; 070 071 /** 072 * The length of the horizontal radii of the bottom-right corner. 073 */ 074 public final double getBottomRightHorizontalRadius() { return bottomRightHorizontalRadius; } 075 private double bottomRightHorizontalRadius; 076 077 /** 078 * The length of the vertical radii of the bottom-right corner. 079 */ 080 public final double getBottomRightVerticalRadius() { return bottomRightVerticalRadius; } 081 private double bottomRightVerticalRadius; 082 083 /** 084 * The length of the vertical radii of the bottom-left corner. 085 */ 086 public final double getBottomLeftVerticalRadius() { return bottomLeftVerticalRadius; } 087 private double bottomLeftVerticalRadius; 088 089 /** 090 * The length of the horizontal radii of the bottom-left corner. 091 */ 092 public final double getBottomLeftHorizontalRadius() { return bottomLeftHorizontalRadius; } 093 private double bottomLeftHorizontalRadius; 094 095 /** 096 * indicates whether {@code topLeftHorizontalRadius} is interpreted as a value or a percentage. 097 */ 098 private final boolean topLeftHorizontalRadiusAsPercentage; 099 public final boolean isTopLeftHorizontalRadiusAsPercentage() { return topLeftHorizontalRadiusAsPercentage; } 100 101 /** 102 * indicates whether {@code topLeftVerticalRadius} is interpreted as a value or a percentage. 103 */ 104 private final boolean topLeftVerticalRadiusAsPercentage; 105 public final boolean isTopLeftVerticalRadiusAsPercentage() { return topLeftVerticalRadiusAsPercentage; } 106 107 /** 108 * indicates whether {@code topRightVerticalRadius} is interpreted as a value or a percentage. 109 */ 110 private final boolean topRightVerticalRadiusAsPercentage; 111 public final boolean isTopRightVerticalRadiusAsPercentage() { return topRightVerticalRadiusAsPercentage; } 112 113 /** 114 * indicates whether {@code topRightHorizontalRadius} is interpreted as a value or a percentage. 115 */ 116 private final boolean topRightHorizontalRadiusAsPercentage; 117 public final boolean isTopRightHorizontalRadiusAsPercentage() { return topRightHorizontalRadiusAsPercentage; } 118 119 /** 120 * indicates whether {@code bottomRightHorizontalRadius} is interpreted as a value or a percentage. 121 */ 122 private final boolean bottomRightHorizontalRadiusAsPercentage; 123 public final boolean isBottomRightHorizontalRadiusAsPercentage() { return bottomRightHorizontalRadiusAsPercentage; } 124 125 /** 126 * indicates whether {@code bottomRightVerticalRadius} is interpreted as a value or a percentage. 127 */ 128 private final boolean bottomRightVerticalRadiusAsPercentage; 129 public final boolean isBottomRightVerticalRadiusAsPercentage() { return bottomRightVerticalRadiusAsPercentage; } 130 131 /** 132 * indicates whether {@code bottomLeftVerticalRadius} is interpreted as a value or a percentage. 133 */ 134 private final boolean bottomLeftVerticalRadiusAsPercentage; 135 public final boolean isBottomLeftVerticalRadiusAsPercentage() { return bottomLeftVerticalRadiusAsPercentage; } 136 137 /** 138 * indicates whether {@code bottomLeftHorizontalRadius} is interpreted as a value or a percentage. 139 */ 140 private final boolean bottomLeftHorizontalRadiusAsPercentage; 141 public final boolean isBottomLeftHorizontalRadiusAsPercentage() { return bottomLeftHorizontalRadiusAsPercentage; } 142 143 final boolean hasPercentBasedRadii; 144 145 /** 146 * Indicates whether each corner radius is exactly the same, and each are either uniformly percentage-based 147 * or not. 148 */ 149 final boolean uniform; 150 public final boolean isUniform() { return uniform; } 151 152 /** 153 * The cached hash code. 154 */ 155 private final int hash; 156 157 /** 158 * Create a new CornerRadii with a single uniform radii value for all components of all 159 * corners. This constructor will create the CornerRadii such that none of the values are 160 * percentages. 161 * 162 * @param radius The radii for each corner. Negative values are not allowed. 163 */ 164 public CornerRadii(double radius) { 165 // As per the CSS Spec 5.1 166 if (radius < 0) { 167 throw new IllegalArgumentException("The radii value may not be < 0"); 168 } 169 this.topLeftHorizontalRadius = this.topLeftVerticalRadius = 170 this.topRightVerticalRadius = this.topRightHorizontalRadius = 171 this.bottomRightHorizontalRadius = this.bottomRightVerticalRadius = 172 this.bottomLeftVerticalRadius = this.bottomLeftHorizontalRadius = radius; 173 174 this.topLeftHorizontalRadiusAsPercentage = this.topLeftVerticalRadiusAsPercentage = 175 this.topRightVerticalRadiusAsPercentage = this.topRightHorizontalRadiusAsPercentage = 176 this.bottomRightHorizontalRadiusAsPercentage = this.bottomRightVerticalRadiusAsPercentage = 177 this.bottomLeftVerticalRadiusAsPercentage = this.bottomLeftHorizontalRadiusAsPercentage = false; 178 179 hasPercentBasedRadii = false; 180 uniform = true; 181 this.hash = preComputeHash(); 182 } 183 184 /** 185 * Create a new CornerRadii with the given radii for each corner. The value is 186 * interpreted either as being a percentage or not based on the {@code asPercent} 187 * argument. 188 * 189 * @param radius The radii for each corner. Negative values are not allowed. 190 * @param asPercent Whether the radii should be interpreted as a percentage. 191 */ 192 public CornerRadii(double radius, boolean asPercent) { 193 if (radius < 0) { 194 throw new IllegalArgumentException("The radii value may not be < 0"); 195 } 196 this.topLeftHorizontalRadius = this.topLeftVerticalRadius = 197 this.topRightVerticalRadius = this.topRightHorizontalRadius = 198 this.bottomRightHorizontalRadius = this.bottomRightVerticalRadius = 199 this.bottomLeftVerticalRadius = this.bottomLeftHorizontalRadius = radius; 200 201 this.topLeftHorizontalRadiusAsPercentage = this.topLeftVerticalRadiusAsPercentage = 202 this.topRightVerticalRadiusAsPercentage = this.topRightHorizontalRadiusAsPercentage = 203 this.bottomRightHorizontalRadiusAsPercentage = this.bottomRightVerticalRadiusAsPercentage = 204 this.bottomLeftVerticalRadiusAsPercentage = this.bottomLeftHorizontalRadiusAsPercentage = asPercent; 205 206 uniform = true; 207 hasPercentBasedRadii = asPercent; 208 this.hash = preComputeHash(); 209 } 210 211 /** 212 * Create a new CornerRadii with uniform yet independent radii for each corner. That is, each corner 213 * can be specified independently, but the horizontal and vertical components of each corner is uniform. 214 * 215 * @param topLeft The radii of the top-left corner. Negative numbers are not allowed. 216 * @param topRight The radii of the top-right corner. Negative numbers are not allowed. 217 * @param bottomRight The radii of the bottom-right corner. Negative numbers are not allowed. 218 * @param bottomLeft The radii of the bottom-left corner. Negative numbers are not allowed. 219 * @param asPercent Whether all four radii should be considered as values or percentages 220 */ 221 public CornerRadii(double topLeft, double topRight, double bottomRight, double bottomLeft, boolean asPercent) { 222 if (topLeft < 0 || topRight < 0 || bottomRight < 0 || bottomLeft < 0) { 223 throw new IllegalArgumentException("No radii value may be < 0"); 224 } 225 226 this.topLeftHorizontalRadius = this.topLeftVerticalRadius = topLeft; 227 this.topRightVerticalRadius = this.topRightHorizontalRadius = topRight; 228 this.bottomRightHorizontalRadius = this.bottomRightVerticalRadius = bottomRight; 229 this.bottomLeftVerticalRadius = this.bottomLeftHorizontalRadius = bottomLeft; 230 this.topLeftHorizontalRadiusAsPercentage = this.topLeftVerticalRadiusAsPercentage = 231 this.topRightVerticalRadiusAsPercentage = this.topRightHorizontalRadiusAsPercentage = 232 this.bottomRightHorizontalRadiusAsPercentage = this.bottomRightVerticalRadiusAsPercentage = 233 this.bottomLeftVerticalRadiusAsPercentage = this.bottomLeftHorizontalRadiusAsPercentage = asPercent; 234 235 uniform = topLeft == topRight && topLeft == bottomLeft && topLeft == bottomRight; 236 hasPercentBasedRadii = asPercent; 237 this.hash = preComputeHash(); 238 } 239 240 /** 241 * Creates a new CornerRadii, allowing for specification of each component of each corner 242 * radii and whether each component should be treated as a value or percentage. 243 * 244 * @param topLeftHorizontalRadius 245 * @param topLeftVerticalRadius 246 * @param topRightVerticalRadius 247 * @param topRightHorizontalRadius 248 * @param bottomRightHorizontalRadius 249 * @param bottomRightVerticalRadius 250 * @param bottomLeftVerticalRadius 251 * @param bottomLeftHorizontalRadius 252 * @param topLeftHorizontalRadiusAsPercent 253 * @param topLeftVerticalRadiusAsPercent 254 * @param topRightVerticalRadiusAsPercent 255 * @param topRightHorizontalRadiusAsPercent 256 * @param bottomRightHorizontalRadiusAsPercent 257 * @param bottomRightVerticalRadiusAsPercent 258 * @param bottomLeftVerticalRadiusAsPercent 259 * @param bottomLeftHorizontalRadiusAsPercent 260 */ 261 public CornerRadii( 262 double topLeftHorizontalRadius, double topLeftVerticalRadius, double topRightVerticalRadius, double topRightHorizontalRadius, 263 double bottomRightHorizontalRadius, double bottomRightVerticalRadius, double bottomLeftVerticalRadius, double bottomLeftHorizontalRadius, 264 boolean topLeftHorizontalRadiusAsPercent, boolean topLeftVerticalRadiusAsPercent, boolean topRightVerticalRadiusAsPercent, 265 boolean topRightHorizontalRadiusAsPercent, boolean bottomRightHorizontalRadiusAsPercent, boolean bottomRightVerticalRadiusAsPercent, 266 boolean bottomLeftVerticalRadiusAsPercent, boolean bottomLeftHorizontalRadiusAsPercent) 267 { 268 if (topLeftHorizontalRadius < 0 || topLeftVerticalRadius < 0 || 269 topRightVerticalRadius < 0 || topRightHorizontalRadius < 0 || 270 bottomRightHorizontalRadius < 0 || bottomRightVerticalRadius < 0 || 271 bottomLeftVerticalRadius < 0 || bottomLeftHorizontalRadius < 0) { 272 throw new IllegalArgumentException("No radii value may be < 0"); 273 } 274 this.topLeftHorizontalRadius = topLeftHorizontalRadius; 275 this.topLeftVerticalRadius = topLeftVerticalRadius; 276 this.topRightVerticalRadius = topRightVerticalRadius; 277 this.topRightHorizontalRadius = topRightHorizontalRadius; 278 this.bottomRightHorizontalRadius = bottomRightHorizontalRadius; 279 this.bottomRightVerticalRadius = bottomRightVerticalRadius; 280 this.bottomLeftVerticalRadius = bottomLeftVerticalRadius; 281 this.bottomLeftHorizontalRadius = bottomLeftHorizontalRadius; 282 this.topLeftHorizontalRadiusAsPercentage = topLeftHorizontalRadiusAsPercent; 283 this.topLeftVerticalRadiusAsPercentage = topLeftVerticalRadiusAsPercent; 284 this.topRightVerticalRadiusAsPercentage = topRightVerticalRadiusAsPercent; 285 this.topRightHorizontalRadiusAsPercentage = topRightHorizontalRadiusAsPercent; 286 this.bottomRightHorizontalRadiusAsPercentage = bottomRightHorizontalRadiusAsPercent; 287 this.bottomRightVerticalRadiusAsPercentage = bottomRightVerticalRadiusAsPercent; 288 this.bottomLeftVerticalRadiusAsPercentage = bottomLeftVerticalRadiusAsPercent; 289 this.bottomLeftHorizontalRadiusAsPercentage = bottomLeftHorizontalRadiusAsPercent; 290 this.hash = preComputeHash(); 291 hasPercentBasedRadii = topLeftHorizontalRadiusAsPercent || topLeftVerticalRadiusAsPercent || 292 topRightVerticalRadiusAsPercent || topRightHorizontalRadiusAsPercent || 293 bottomRightHorizontalRadiusAsPercent || bottomRightVerticalRadiusAsPercent || 294 bottomLeftVerticalRadiusAsPercent || bottomLeftHorizontalRadiusAsPercent; 295 uniform = topLeftHorizontalRadius == topRightHorizontalRadius && 296 topLeftVerticalRadius == topRightVerticalRadius && 297 topLeftHorizontalRadius == bottomRightHorizontalRadius && 298 topLeftVerticalRadius == bottomRightVerticalRadius && 299 topLeftHorizontalRadius == bottomLeftHorizontalRadius && 300 topLeftVerticalRadius == bottomLeftVerticalRadius && 301 topLeftHorizontalRadiusAsPercent == topRightHorizontalRadiusAsPercent && 302 topLeftVerticalRadiusAsPercent == topRightVerticalRadiusAsPercent && 303 topLeftHorizontalRadiusAsPercent == bottomRightHorizontalRadiusAsPercent && 304 topLeftVerticalRadiusAsPercent == bottomRightVerticalRadiusAsPercent && 305 topLeftHorizontalRadiusAsPercent == bottomLeftHorizontalRadiusAsPercent && 306 topLeftVerticalRadiusAsPercent == bottomLeftVerticalRadiusAsPercent; 307 } 308 309 private int preComputeHash() { 310 int result; 311 long temp; 312 temp = topLeftHorizontalRadius != +0.0d ? Double.doubleToLongBits(topLeftHorizontalRadius) : 0L; 313 result = (int) (temp ^ (temp >>> 32)); 314 temp = topLeftVerticalRadius != +0.0d ? Double.doubleToLongBits(topLeftVerticalRadius) : 0L; 315 result = 31 * result + (int) (temp ^ (temp >>> 32)); 316 temp = topRightVerticalRadius != +0.0d ? Double.doubleToLongBits(topRightVerticalRadius) : 0L; 317 result = 31 * result + (int) (temp ^ (temp >>> 32)); 318 temp = topRightHorizontalRadius != +0.0d ? Double.doubleToLongBits(topRightHorizontalRadius) : 0L; 319 result = 31 * result + (int) (temp ^ (temp >>> 32)); 320 temp = bottomRightHorizontalRadius != +0.0d ? Double.doubleToLongBits(bottomRightHorizontalRadius) : 0L; 321 result = 31 * result + (int) (temp ^ (temp >>> 32)); 322 temp = bottomRightVerticalRadius != +0.0d ? Double.doubleToLongBits(bottomRightVerticalRadius) : 0L; 323 result = 31 * result + (int) (temp ^ (temp >>> 32)); 324 temp = bottomLeftVerticalRadius != +0.0d ? Double.doubleToLongBits(bottomLeftVerticalRadius) : 0L; 325 result = 31 * result + (int) (temp ^ (temp >>> 32)); 326 temp = bottomLeftHorizontalRadius != +0.0d ? Double.doubleToLongBits(bottomLeftHorizontalRadius) : 0L; 327 result = 31 * result + (int) (temp ^ (temp >>> 32)); 328 result = 31 * result + (topLeftHorizontalRadiusAsPercentage ? 1 : 0); 329 result = 31 * result + (topLeftVerticalRadiusAsPercentage ? 1 : 0); 330 result = 31 * result + (topRightVerticalRadiusAsPercentage ? 1 : 0); 331 result = 31 * result + (topRightHorizontalRadiusAsPercentage ? 1 : 0); 332 result = 31 * result + (bottomRightHorizontalRadiusAsPercentage ? 1 : 0); 333 result = 31 * result + (bottomRightVerticalRadiusAsPercentage ? 1 : 0); 334 result = 31 * result + (bottomLeftVerticalRadiusAsPercentage ? 1 : 0); 335 result = 31 * result + (bottomLeftHorizontalRadiusAsPercentage ? 1 : 0); 336 result = 31 * result + result; 337 return result; 338 } 339 340 /** 341 * @inheritDoc 342 */ 343 @Override public boolean equals(Object o) { 344 if (this == o) return true; 345 if (o == null || getClass() != o.getClass()) return false; 346 CornerRadii that = (CornerRadii) o; 347 if (this.hash != that.hash) return false; 348 349 if (Double.compare(that.bottomLeftHorizontalRadius, bottomLeftHorizontalRadius) != 0) return false; 350 if (bottomLeftHorizontalRadiusAsPercentage != that.bottomLeftHorizontalRadiusAsPercentage) return false; 351 if (Double.compare(that.bottomLeftVerticalRadius, bottomLeftVerticalRadius) != 0) return false; 352 if (bottomLeftVerticalRadiusAsPercentage != that.bottomLeftVerticalRadiusAsPercentage) return false; 353 if (Double.compare(that.bottomRightVerticalRadius, bottomRightVerticalRadius) != 0) return false; 354 if (bottomRightVerticalRadiusAsPercentage != that.bottomRightVerticalRadiusAsPercentage) return false; 355 if (Double.compare(that.bottomRightHorizontalRadius, bottomRightHorizontalRadius) != 0) return false; 356 if (bottomRightHorizontalRadiusAsPercentage != that.bottomRightHorizontalRadiusAsPercentage) return false; 357 if (Double.compare(that.topLeftVerticalRadius, topLeftVerticalRadius) != 0) return false; 358 if (topLeftVerticalRadiusAsPercentage != that.topLeftVerticalRadiusAsPercentage) return false; 359 if (Double.compare(that.topLeftHorizontalRadius, topLeftHorizontalRadius) != 0) return false; 360 if (topLeftHorizontalRadiusAsPercentage != that.topLeftHorizontalRadiusAsPercentage) return false; 361 if (Double.compare(that.topRightHorizontalRadius, topRightHorizontalRadius) != 0) return false; 362 if (topRightHorizontalRadiusAsPercentage != that.topRightHorizontalRadiusAsPercentage) return false; 363 if (Double.compare(that.topRightVerticalRadius, topRightVerticalRadius) != 0) return false; 364 if (topRightVerticalRadiusAsPercentage != that.topRightVerticalRadiusAsPercentage) return false; 365 366 return true; 367 } 368 369 /** 370 * @inheritDoc 371 */ 372 @Override public int hashCode() { 373 return hash; 374 } 375 376 @Override public String toString() { 377 if (isUniform()) { 378 return "CornerRadii [uniform radius = " + topLeftHorizontalRadius + "]"; 379 } 380 381 return "CornerRadii [" + 382 (topLeftHorizontalRadius == topLeftVerticalRadius ? 383 "topLeft=" + topLeftHorizontalRadius : 384 "topLeftHorizontalRadius=" + topLeftHorizontalRadius + 385 ", topLeftVerticalRadius=" + topLeftVerticalRadius) + 386 (topRightHorizontalRadius == topRightVerticalRadius ? 387 ", topRight=" + topRightHorizontalRadius : 388 ", topRightVerticalRadius=" + topRightVerticalRadius + 389 ", topRightHorizontalRadius=" + topRightHorizontalRadius) + 390 (bottomRightHorizontalRadius == bottomRightVerticalRadius ? 391 ", bottomRight=" + bottomRightHorizontalRadius : 392 ", bottomRightHorizontalRadius=" + bottomRightHorizontalRadius + 393 ", bottomRightVerticalRadius=" + bottomRightVerticalRadius) + 394 (bottomLeftHorizontalRadius == bottomLeftVerticalRadius ? 395 ", bottomLeft=" + bottomLeftHorizontalRadius : 396 ", bottomLeftVerticalRadius=" + bottomLeftVerticalRadius + 397 ", bottomLeftHorizontalRadius=" + bottomLeftHorizontalRadius) + 398// ", topLeftHorizontalRadiusAsPercentage=" + topLeftHorizontalRadiusAsPercentage + 399// ", topLeftVerticalRadiusAsPercentage=" + topLeftVerticalRadiusAsPercentage + 400// ", topRightVerticalRadiusAsPercentage=" + topRightVerticalRadiusAsPercentage + 401// ", topRightHorizontalRadiusAsPercentage=" + topRightHorizontalRadiusAsPercentage + 402// ", bottomRightHorizontalRadiusAsPercentage=" + bottomRightHorizontalRadiusAsPercentage + 403// ", bottomRightVerticalRadiusAsPercentage=" + bottomRightVerticalRadiusAsPercentage + 404// ", bottomLeftVerticalRadiusAsPercentage=" + bottomLeftVerticalRadiusAsPercentage + 405// ", bottomLeftHorizontalRadiusAsPercentage=" + bottomLeftHorizontalRadiusAsPercentage + 406// ", hasPercentBasedRadii=" + hasPercentBasedRadii + 407// ", uniform=" + uniform + 408 ']'; 409 } 410}