53 /** 54 * The default insets when "medium" is specified 55 */ 56 public static final BorderWidths MEDIUM = new BorderWidths(3); 57 58 /** 59 * The default insets when "thick" is specified 60 */ 61 public static final BorderWidths THICK = new BorderWidths(5); 62 63 /** 64 * The default Insets to be used with a BorderStroke that does not 65 * otherwise define any. 66 */ 67 public static final BorderWidths DEFAULT_WIDTHS = THIN; 68 69 /** 70 * Defines the fill of top side of this border. 71 * 72 * @return the fill of top side of this border 73 * @defaultValue black 74 */ 75 public final Paint getTopStroke() { return topStroke; } 76 final Paint topStroke; 77 // TODO: The spec says the default color is "currentColor", which appears to mean 78 // by default the color is "inherit". So we should file a JIRA on this so that 79 // we use inherit. But first I'd like a performance analysis. 80 81 /** 82 * Defines the fill of right side of this border. If {@code null} then the 83 * topFill is used. 84 * 85 * @return the fill of right side of this border 86 * @defaultValue null = same as topFill 87 */ 88 public final Paint getRightStroke() { return rightStroke; } 89 final Paint rightStroke; 90 91 /** 92 * Defines the fill of bottom side of this border. If {@code null} then the 93 * topFill is used. 94 * 95 * @return the fill of bottom side of this border 96 * @defaultValue null = same as topFill 97 */ 98 public final Paint getBottomStroke() { return bottomStroke; } 99 final Paint bottomStroke; 100 101 /** 102 * Defines the fill of left side of this border. If {@code null} then the 103 * rightFill is used. 104 * 105 * @return the fill of left side of this border 106 * @defaultValue null = same sa rightFill 107 */ 108 public final Paint getLeftStroke() { return leftStroke; } 109 final Paint leftStroke; 110 111 /** 112 * Defines the style of top side of this border. 113 * 114 * @return the style of top side of this border 115 * @defaultValue none 116 */ 117 public final BorderStrokeStyle getTopStyle() { return topStyle; } 118 final BorderStrokeStyle topStyle; 119 120 /** 121 * Defines the style of right side of this border. If {@code null} then 122 * topStyle is used; 123 * 124 * @return the style of right side of this border 125 * @defaultValue null = same as topStyle 126 */ 127 public final BorderStrokeStyle getRightStyle() { return rightStyle; } 128 final BorderStrokeStyle rightStyle; 129 130 /** 131 * Defines the style of bottom side of this border. If {@code null} then 132 * topStyle is used; Use BorderStyle.NONE to set the border to 133 * have no border style. 134 * 135 * @return the style of bottom side of this border 136 * @defaultValue null = same as topStyle 137 */ 138 public final BorderStrokeStyle getBottomStyle() { return bottomStyle; } 139 final BorderStrokeStyle bottomStyle; 140 141 /** 142 * Defines the style of left side of this border. If {@code null} then 143 * rightStyle is used. Use BorderStyle.NONE to set the border to 144 * have no border style. 145 * 146 * @return the style of left side of this border 147 * @defaultValue null = same as rightStyle 148 */ 149 public final BorderStrokeStyle getLeftStyle() { return leftStyle; } 150 final BorderStrokeStyle leftStyle; 151 152 /** 153 * Defines the thickness of each side of the BorderStroke. This will never 154 * be null, and defaults to DEFAULT_WIDTHS. 155 * @return the thickness of each side of the BorderStroke 156 */ 157 public final BorderWidths getWidths() { return widths; } 158 final BorderWidths widths; 159 160 /** 161 * Defines the insets of each side of the BorderStroke. This will never 162 * be null, and defaults to EMPTY. 163 * @return the insets of each side of the BorderStroke 164 */ 165 public final Insets getInsets() { return insets; } 166 final Insets insets; 167 168 // These two are used by Border to compute the insets and outsets of the border 169 final Insets innerEdge; 170 final Insets outerEdge; 171 172 /** 173 * Defines the radii for each corner of this BorderStroke. This will never 174 * be null, and defaults to CornerRadii.EMPTY. 175 * @return the radii for each corner of this BorderStroke 176 */ 177 public final CornerRadii getRadii() { return radii; } 178 /* TODO I should change CornerRadii to be 4 properties, one for each corner, 179 * where each corner is a horizontal / vertical radius! I think that would 180 * be cleaner. */ 181 private final CornerRadii radii; 182 183 /** 184 * An uniform stroke has all (top, bottom, left, right) strokes of 185 * same color, width and style 186 * @return true if border stroke is uniform as defined above 187 */ 188 public final boolean isStrokeUniform() { return strokeUniform; } 189 private final boolean strokeUniform; 190 191 /** 192 * A cached hash code 193 */ 194 private final int hash; 195 196 /** 197 * Creates a new BorderStroke. 198 * 199 * @param stroke The stroke to use for all sides. If null, we default to Color.BLACK. 200 * @param style The style to use for all sides. If null, we default to BorderStrokeStyle.NONE 201 * @param radii The radii to use. If null, we default to CornerRadii.EMPTY 202 * @param widths The widths to use. If null, we default to DEFAULT_WIDTHS 203 */ 204 public BorderStroke(@NamedArg("stroke") Paint stroke, @NamedArg("style") BorderStrokeStyle style, @NamedArg("radii") CornerRadii radii, @NamedArg("widths") BorderWidths widths) { 205 // TODO: Note that we default to THIN, not to MEDIUM as the CSS spec says. So it will be 206 // up to our CSS converter code to make sure the default is MEDIUM in that case. 207 this.leftStroke = this.topStroke = this.rightStroke = this.bottomStroke = stroke == null ? Color.BLACK : stroke; 208 this.topStyle = this.rightStyle = this.bottomStyle = this.leftStyle = style == null ? BorderStrokeStyle.NONE : style; 209 this.radii = radii == null ? CornerRadii.EMPTY : radii; 210 this.widths = widths == null ? DEFAULT_WIDTHS : widths; 211 this.insets = Insets.EMPTY; 212 213 // TODO: Our inside / outside should be 0 when stroke type is NONE in that dimension! 214 // In fact, we could adjust the widths in such a case so that when you ask for the 215 // widths, you get 0 instead of whatever was specified. See 4.3 of the CSS Spec. 216 217 // Strokes can only differ in width 218 strokeUniform = this.widths.left == this.widths.top && 219 this.widths.left == this.widths.right && 220 this.widths.left == this.widths.bottom; 221 222 // Since insets are empty, don't have to worry about it 223 innerEdge = new Insets( 224 computeInside(this.topStyle.getType(), this.widths.getTop()), 225 computeInside(this.rightStyle.getType(), this.widths.getRight()), 226 computeInside(this.bottomStyle.getType(), this.widths.getBottom()), 227 computeInside(this.leftStyle.getType(), this.widths.getLeft()) 228 ); 229 outerEdge = new Insets( 230 Math.max(0, computeOutside(this.topStyle.getType(), this.widths.getTop())), 231 Math.max(0, computeOutside(this.rightStyle.getType(), this.widths.getRight())), 232 Math.max(0, computeOutside(this.bottomStyle.getType(), this.widths.getBottom())), 233 Math.max(0, computeOutside(this.leftStyle.getType(), this.widths.getLeft())) 234 ); 235 this.hash = preComputeHash(); 236 } 237 238 /** 239 * Creates a new BorderStroke. 240 * 241 * @param stroke The stroke to use for all sides. If null, we default to Color.BLACK. 242 * @param style The style to use for all sides. If null, we default to BorderStrokeStyle.NONE 243 * @param radii The radii to use. If null, we default to CornerRadii.EMPTY 244 * @param widths The widths to use. If null, we default to DEFAULT_WIDTHS 245 * @param insets The insets indicating where to draw the border relative to the region edges. 246 */ 247 public BorderStroke(@NamedArg("stroke") Paint stroke, @NamedArg("style") BorderStrokeStyle style, @NamedArg("radii") CornerRadii radii, @NamedArg("widths") BorderWidths widths, @NamedArg("insets") Insets insets) { 248 this(stroke, stroke, stroke, stroke, style, style, style, style, radii, widths, insets); 249 } 250 251 /** 252 * Create a new BorderStroke, specifying all construction parameters. 253 * 254 * @param topStroke The fill to use on the top. If null, defaults to BLACK. 255 * @param rightStroke The fill to use on the right. If null, defaults to the same value as topStroke 256 * @param bottomStroke The fill to use on the bottom. If null, defaults to the same value as bottomStroke 257 * @param leftStroke The fill to use on the left. If null, defaults to the same value as rightStroke 258 * @param topStyle The style to use on the top. If null, defaults to BorderStrokeStyle.NONE 259 * @param rightStyle The style to use on the right. If null, defaults to the same value as topStyle 260 * @param bottomStyle The style to use on the bottom. If null, defaults to the same value as topStyle 261 * @param leftStyle The style to use on the left. If null, defaults to the same value as rightStyle 262 * @param radii The radii. If null, we default to square corners by using CornerRadii.EMPTY 263 * @param widths The thickness of each side. If null, we default to DEFAULT_WIDTHS. 264 * @param insets The insets indicating where to draw the border relative to the region edges. 265 */ 266 public BorderStroke( 267 @NamedArg("topStroke") Paint topStroke, @NamedArg("rightStroke") Paint rightStroke, @NamedArg("bottomStroke") Paint bottomStroke, @NamedArg("leftStroke") Paint leftStroke, 268 @NamedArg("topStyle") BorderStrokeStyle topStyle, @NamedArg("rightStyle") BorderStrokeStyle rightStyle, 269 @NamedArg("bottomStyle") BorderStrokeStyle bottomStyle, @NamedArg("leftStyle") BorderStrokeStyle leftStyle, 270 @NamedArg("radii") CornerRadii radii, @NamedArg("widths") BorderWidths widths, @NamedArg("insets") Insets insets) 271 { 272 this.topStroke = topStroke == null ? Color.BLACK : topStroke; 273 this.rightStroke = rightStroke == null ? this.topStroke : rightStroke; 274 this.bottomStroke = bottomStroke == null ? this.topStroke : bottomStroke; 275 this.leftStroke = leftStroke == null ? this.rightStroke : leftStroke; 276 this.topStyle = topStyle == null ? BorderStrokeStyle.NONE : topStyle; 277 this.rightStyle = rightStyle == null ? this.topStyle : rightStyle; 278 this.bottomStyle = bottomStyle == null ? this.topStyle : bottomStyle; 279 this.leftStyle = leftStyle == null ? this.rightStyle : leftStyle; 280 this.radii = radii == null ? CornerRadii.EMPTY : radii; 281 this.widths = widths == null ? DEFAULT_WIDTHS : widths; 282 this.insets = insets == null ? Insets.EMPTY : insets; 283 284 | 53 /** 54 * The default insets when "medium" is specified 55 */ 56 public static final BorderWidths MEDIUM = new BorderWidths(3); 57 58 /** 59 * The default insets when "thick" is specified 60 */ 61 public static final BorderWidths THICK = new BorderWidths(5); 62 63 /** 64 * The default Insets to be used with a BorderStroke that does not 65 * otherwise define any. 66 */ 67 public static final BorderWidths DEFAULT_WIDTHS = THIN; 68 69 /** 70 * Defines the fill of top side of this border. 71 * 72 * @return the fill of top side of this border 73 * @defaultValue Color.BLACK 74 */ 75 public final Paint getTopStroke() { return topStroke; } 76 final Paint topStroke; 77 // TODO: The spec says the default color is "currentColor", which appears to mean 78 // by default the color is "inherit". So we should file a JIRA on this so that 79 // we use inherit. But first I'd like a performance analysis. 80 81 /** 82 * Defines the fill of right side of this border. If {@code null}, then the 83 * topFill is used. 84 * 85 * @return the fill of right side of this border 86 * @defaultValue null (same as topFill) 87 */ 88 public final Paint getRightStroke() { return rightStroke; } 89 final Paint rightStroke; 90 91 /** 92 * Defines the fill of bottom side of this border. If {@code null}, then the 93 * topFill is used. 94 * 95 * @return the fill of bottom side of this border 96 * @defaultValue null (same as topFill) 97 */ 98 public final Paint getBottomStroke() { return bottomStroke; } 99 final Paint bottomStroke; 100 101 /** 102 * Defines the fill of left side of this border. If {@code null}, then the 103 * rightFill is used. 104 * 105 * @return the fill of left side of this border 106 * @defaultValue null (same as rightFill) 107 */ 108 public final Paint getLeftStroke() { return leftStroke; } 109 final Paint leftStroke; 110 111 /** 112 * Defines the style of top side of this border. 113 * 114 * @return the style of top side of this border 115 * @defaultValue BorderStrokeStyle.NONE 116 */ 117 public final BorderStrokeStyle getTopStyle() { return topStyle; } 118 final BorderStrokeStyle topStyle; 119 120 /** 121 * Defines the style of right side of this border. If {@code null}, then 122 * topStyle is used; 123 * 124 * @return the style of right side of this border 125 * @defaultValue null (same as topStyle) 126 */ 127 public final BorderStrokeStyle getRightStyle() { return rightStyle; } 128 final BorderStrokeStyle rightStyle; 129 130 /** 131 * Defines the style of bottom side of this border. If {@code null}, then 132 * topStyle is used; Use BorderStyle.NONE to set the border to 133 * have no border style. 134 * 135 * @return the style of bottom side of this border 136 * @defaultValue null (same as topStyle) 137 */ 138 public final BorderStrokeStyle getBottomStyle() { return bottomStyle; } 139 final BorderStrokeStyle bottomStyle; 140 141 /** 142 * Defines the style of left side of this border. If {@code null}, then 143 * rightStyle is used. Use BorderStyle.NONE to set the border to 144 * have no border style. 145 * 146 * @return the style of left side of this border 147 * @defaultValue null (same as rightStyle) 148 */ 149 public final BorderStrokeStyle getLeftStyle() { return leftStyle; } 150 final BorderStrokeStyle leftStyle; 151 152 /** 153 * Defines the thickness of each side of the BorderStroke. This will never 154 * be null, and defaults to DEFAULT_WIDTHS. 155 * @return the thickness of each side of the BorderStroke 156 */ 157 public final BorderWidths getWidths() { return widths; } 158 final BorderWidths widths; 159 160 /** 161 * Defines the insets of each side of the BorderStroke. This will never 162 * be null, and defaults to EMPTY. 163 * @return the insets of each side of the BorderStroke 164 */ 165 public final Insets getInsets() { return insets; } 166 final Insets insets; 167 168 // These two are used by Border to compute the insets and outsets of the border 169 final Insets innerEdge; 170 final Insets outerEdge; 171 172 /** 173 * Defines the radii for each corner of this BorderStroke. This will never 174 * be null, and defaults to CornerRadii.EMPTY. 175 * @return the radii for each corner of this BorderStroke 176 */ 177 public final CornerRadii getRadii() { return radii; } 178 /* TODO I should change CornerRadii to be 4 properties, one for each corner, 179 * where each corner is a horizontal / vertical radius! I think that would 180 * be cleaner. */ 181 private final CornerRadii radii; 182 183 /** 184 * Checks if the stroke of this region is uniform. A uniform stroke has all its side 185 * strokes (top, bottom, left, right) of same color, width and style. 186 * @return true if border stroke is uniform 187 */ 188 public final boolean isStrokeUniform() { return strokeUniform; } 189 private final boolean strokeUniform; 190 191 /** 192 * A cached hash code 193 */ 194 private final int hash; 195 196 /** 197 * Creates a new BorderStroke. 198 * 199 * @param stroke The stroke to use for all sides. If null, defaults to Color.BLACK. 200 * @param style The style to use for all sides. If null, defaults to BorderStrokeStyle.NONE. 201 * @param radii The radii to use. If null, defaults to CornerRadii.EMPTY. 202 * @param widths The widths to use. If null, defaults to DEFAULT_WIDTHS. 203 */ 204 public BorderStroke(@NamedArg("stroke") Paint stroke, @NamedArg("style") BorderStrokeStyle style, @NamedArg("radii") CornerRadii radii, @NamedArg("widths") BorderWidths widths) { 205 // TODO: Note that we default to THIN, not to MEDIUM as the CSS spec says. So it will be 206 // up to our CSS converter code to make sure the default is MEDIUM in that case. 207 this.leftStroke = this.topStroke = this.rightStroke = this.bottomStroke = stroke == null ? Color.BLACK : stroke; 208 this.topStyle = this.rightStyle = this.bottomStyle = this.leftStyle = style == null ? BorderStrokeStyle.NONE : style; 209 this.radii = radii == null ? CornerRadii.EMPTY : radii; 210 this.widths = widths == null ? DEFAULT_WIDTHS : widths; 211 this.insets = Insets.EMPTY; 212 213 // TODO: Our inside / outside should be 0 when stroke type is NONE in that dimension! 214 // In fact, we could adjust the widths in such a case so that when you ask for the 215 // widths, you get 0 instead of whatever was specified. See 4.3 of the CSS Spec. 216 217 // Strokes can only differ in width 218 strokeUniform = this.widths.left == this.widths.top && 219 this.widths.left == this.widths.right && 220 this.widths.left == this.widths.bottom; 221 222 // Since insets are empty, don't have to worry about it 223 innerEdge = new Insets( 224 computeInside(this.topStyle.getType(), this.widths.getTop()), 225 computeInside(this.rightStyle.getType(), this.widths.getRight()), 226 computeInside(this.bottomStyle.getType(), this.widths.getBottom()), 227 computeInside(this.leftStyle.getType(), this.widths.getLeft()) 228 ); 229 outerEdge = new Insets( 230 Math.max(0, computeOutside(this.topStyle.getType(), this.widths.getTop())), 231 Math.max(0, computeOutside(this.rightStyle.getType(), this.widths.getRight())), 232 Math.max(0, computeOutside(this.bottomStyle.getType(), this.widths.getBottom())), 233 Math.max(0, computeOutside(this.leftStyle.getType(), this.widths.getLeft())) 234 ); 235 this.hash = preComputeHash(); 236 } 237 238 /** 239 * Creates a new BorderStroke. 240 * 241 * @param stroke The stroke to use for all sides. If null, defaults to Color.BLACK. 242 * @param style The style to use for all sides. If null, defaults to BorderStrokeStyle.NONE. 243 * @param radii The radii to use. If null, defaults to CornerRadii.EMPTY. 244 * @param widths The widths to use. If null, defaults to DEFAULT_WIDTHS. 245 * @param insets The insets indicating where to draw the border relative to the region edges. 246 * If null, defaults to Insets.EMPTY. 247 */ 248 public BorderStroke(@NamedArg("stroke") Paint stroke, @NamedArg("style") BorderStrokeStyle style, @NamedArg("radii") CornerRadii radii, @NamedArg("widths") BorderWidths widths, @NamedArg("insets") Insets insets) { 249 this(stroke, stroke, stroke, stroke, style, style, style, style, radii, widths, insets); 250 } 251 252 /** 253 * Create a new BorderStroke, specifying all construction parameters. 254 * 255 * @param topStroke The fill to use on the top. If null, defaults to Color.BLACK. 256 * @param rightStroke The fill to use on the right. If null, defaults to the same value as topStroke. 257 * @param bottomStroke The fill to use on the bottom. If null, defaults to the same value as topStroke. 258 * @param leftStroke The fill to use on the left. If null, defaults to the same value as rightStroke. 259 * @param topStyle The style to use on the top. If null, defaults to BorderStrokeStyle.NONE. 260 * @param rightStyle The style to use on the right. If null, defaults to the same value as topStyle. 261 * @param bottomStyle The style to use on the bottom. If null, defaults to the same value as topStyle. 262 * @param leftStyle The style to use on the left. If null, defaults to the same value as rightStyle. 263 * @param radii The radii. If null, defaults to square corners by using CornerRadii.EMPTY. 264 * @param widths The thickness of each side. If null, defaults to DEFAULT_WIDTHS. 265 * @param insets The insets indicating where to draw the border relative to the region edges. 266 * If null, defaults to Insets.EMPTY. 267 */ 268 public BorderStroke( 269 @NamedArg("topStroke") Paint topStroke, @NamedArg("rightStroke") Paint rightStroke, @NamedArg("bottomStroke") Paint bottomStroke, @NamedArg("leftStroke") Paint leftStroke, 270 @NamedArg("topStyle") BorderStrokeStyle topStyle, @NamedArg("rightStyle") BorderStrokeStyle rightStyle, 271 @NamedArg("bottomStyle") BorderStrokeStyle bottomStyle, @NamedArg("leftStyle") BorderStrokeStyle leftStyle, 272 @NamedArg("radii") CornerRadii radii, @NamedArg("widths") BorderWidths widths, @NamedArg("insets") Insets insets) 273 { 274 this.topStroke = topStroke == null ? Color.BLACK : topStroke; 275 this.rightStroke = rightStroke == null ? this.topStroke : rightStroke; 276 this.bottomStroke = bottomStroke == null ? this.topStroke : bottomStroke; 277 this.leftStroke = leftStroke == null ? this.rightStroke : leftStroke; 278 this.topStyle = topStyle == null ? BorderStrokeStyle.NONE : topStyle; 279 this.rightStyle = rightStyle == null ? this.topStyle : rightStyle; 280 this.bottomStyle = bottomStyle == null ? this.topStyle : bottomStyle; 281 this.leftStyle = leftStyle == null ? this.rightStyle : leftStyle; 282 this.radii = radii == null ? CornerRadii.EMPTY : radii; 283 this.widths = widths == null ? DEFAULT_WIDTHS : widths; 284 this.insets = insets == null ? Insets.EMPTY : insets; 285 286 |