/*
* Copyright 2000-2018 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.ui.components.colorpicker;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.vaadin.shared.ui.colorpicker.Color;
/**
* Utility class for matching and parsing {@link Color} objects from
* {@code String} input.
*
* Description of supported formats see
* http://www.w3schools.com/cssref/css_colors_legal.asp
*
* @since
*/
public class ColorUtil {
private ColorUtil() {
}
/**
* Parses {@link Color} from any of the following {@link String} inputs:
*
* - RGB hex (e.g. "#FFAA00"), {@link #HEX_PATTERN}
* - RGB "function" (e.g. "rgb(128,0,255)"), {@link #RGB_PATTERN}
* - RGBA "function" (e.g. "rgba(50,50,50,0.2)"), {@link #RGBA_PATTERN}
* - HSL "function" (e.g. "hsl(50,50,50)"), {@link #HSL_PATTERN}
* - HSLA "function" (e.g. "hsl(50,50,50,0.2)"), {@link #HSLA_PATTERN}
*
* Parsing is case-insensitive.
*
* @param input
* String input
* @return {@link Color} parsed from input
* @throws NumberFormatException
* Input does not match any recognized pattern
*/
public static Color stringToColor(String input) {
Matcher m = HEX_PATTERN.matcher(input);
if (m.matches()) {
return getHexPatternColor(m);
}
m = RGB_PATTERN.matcher(input);
if (m.matches()) {
return getRGBPatternColor(m);
}
m = RGBA_PATTERN.matcher(input);
if (m.matches()) {
return getRGBAPatternColor(m);
}
m = HSL_PATTERN.matcher(input);
if (m.matches()) {
return getHSLPatternColor(m);
}
m = HSLA_PATTERN.matcher(input);
if (m.matches()) {
return getHSLAPatternColor(m);
}
throw new NumberFormatException("Parsing color from input failed.");
}
/**
* Parses {@link Color} from matched hexadecimal {@link Matcher}.
*
* @param matcher
* {@link Matcher} matching hexadecimal pattern with named regex
* groups {@code red}, {@code green}, and {@code blue}
* @return {@link Color} parsed from {@link Matcher}
*/
public static Color getHexPatternColor(Matcher matcher) {
int red = Integer.parseInt(matcher.group("red"), 16);
int green = Integer.parseInt(matcher.group("green"), 16);
int blue = Integer.parseInt(matcher.group("blue"), 16);
return new Color(red, green, blue);
}
/**
* Parses {@link Color} from matched RGB {@link Matcher}.
*
* @param matcher
* {@link Matcher} matching RGB pattern with named regex groups
* {@code red}, {@code green}, and {@code blue}
* @return {@link Color} parsed from {@link Matcher}
*/
public static Color getRGBPatternColor(Matcher matcher) {
int red = Integer.parseInt(matcher.group("red"));
int green = Integer.parseInt(matcher.group("green"));
int blue = Integer.parseInt(matcher.group("blue"));
return new Color(red, green, blue);
}
/**
* Parses {@link Color} from matched RGBA {@link Matcher}.
*
* @param matcher
* {@link Matcher} matching RGBA pattern with named regex groups
* {@code red}, {@code green}, {@code blue}, and {@code alpha}
* @return {@link Color} parsed from {@link Matcher}
*/
public static Color getRGBAPatternColor(Matcher matcher) {
Color c = getRGBPatternColor(matcher);
c.setAlpha((int) (Double.parseDouble(matcher.group("alpha")) * 255d));
return c;
}
/**
* Parses {@link Color} from matched HSL {@link Matcher}.
*
* @param matcher
* {@link Matcher} matching HSL pattern with named regex groups
* {@code hue}, {@code saturation}, and {@code light}
* @return {@link Color} parsed from {@link Matcher}
*/
public static Color getHSLPatternColor(Matcher matcher) {
int hue = Integer.parseInt(matcher.group("hue"));
int saturation = Integer.parseInt(matcher.group("saturation"));
int light = Integer.parseInt(matcher.group("light"));
int rgb = Color.HSLtoRGB(hue, saturation, light);
return new Color(rgb);
}
/**
* Parses {@link Color} from matched HSLA {@link Matcher}.
*
* @param matcher
* {@link Matcher} matching HSLA pattern with named regex groups
* {@code hue}, {@code saturation}, {@code light}, and
* {@code alpha}
* @return {@link Color} parsed from {@link Matcher}
*/
public static Color getHSLAPatternColor(Matcher matcher) {
Color c = getHSLPatternColor(matcher);
c.setAlpha((int) (Double.parseDouble(matcher.group("alpha")) * 255d));
return c;
}
/**
* Case-insensitive {@link Pattern} with regular expression matching the
* default hexadecimal color presentation pattern:
* '#' followed by six [\da-fA-F]
characters.
*
* Pattern contains named groups
* Pattern contains named groups
* Pattern contains named groups
* Pattern contains named groups
* Pattern contains named groups red
, green
, and
* blue
, which represent the individual values.
*/
public static final Pattern HEX_PATTERN = Pattern.compile(
"(?i)^#\\s*(?
* 'rgb' followed by three [0-255] number values. Values can be separated
* with either comma or whitespace.
* red
, green
, and
* blue
, which represent the individual values.
*/
public static final Pattern RGB_PATTERN = Pattern.compile(
"(?i)^rgb\\(\\s*(?
* 'rgba' followed by three [0-255] values and one [0.0-1.0] value. Values
* can be separated with either comma or whitespace. The only accepted
* decimal marker is point ('.').
* red
, green
,
* blue
, and alpha
, which represent the individual
* values.
*/
public static final Pattern RGBA_PATTERN = Pattern.compile(
"(?i)^rgba\\(\\s*(?
* 'hsl' followed by one [0-360] value and two [0-100] percentage value.
* Values can be separated with either comma or whitespace. The percent sign
* ('%') is optional.
* hue
,saturation
,
* and light
, which represent the individual values.
*/
public static final Pattern HSL_PATTERN = Pattern.compile(
"(?i)hsl\\(\\s*(?
* 'hsla' followed by one [0-360] value, two [0-100] percentage values, and
* one [0.0-1.0] value. Values can be separated with either comma or
* whitespace. The percent sign ('%') is optional. The only accepted decimal
* marker is point ('.').
* hue
,saturation
,
* light
, and alpha
, which represent the
* individual values.
*/
public static final Pattern HSLA_PATTERN = Pattern.compile(
"(?i)hsla\\(\\s*(?