package com.github.sommeri.less4j.core.ast; import java.awt.Color; import java.util.Collections; import java.util.List; import com.github.sommeri.less4j.core.ast.annotations.NotAstProperty; import com.github.sommeri.less4j.core.parser.HiddenTokenAwareTree; import com.github.sommeri.less4j.utils.PrintUtils; public class ColorExpression extends Expression { protected String value; protected double red; protected double green; protected double blue; ColorExpression(HiddenTokenAwareTree token, ColorExpression colorExpression) { super(token); red = colorExpression.red; green = colorExpression.green; blue = colorExpression.blue; this.value = encode(red, green, blue); } public ColorExpression(HiddenTokenAwareTree token, double red, double green, double blue) { super(token); this.red = red; this.green = green; this.blue = blue; this.value = encode(red, green, blue); } public ColorExpression(HiddenTokenAwareTree token, String value, double red, double green, double blue) { super(token); this.red = red; this.green = green; this.blue = blue; this.value = value; } public String getValue() { return value; } public boolean isShorthand() { String value = getValue(); return !isNamed() && value!=null && value.length() < 7; } public String getValueInHexadecimal() { return encode(red, green, blue); } public void setValue(String value) { this.value = value; red = decode(value, 0); green = decode(value, 1); blue = decode(value, 2); } public double getRed() { return red; } public double getGreen() { return green; } public double getBlue() { return blue; } public double getAlpha() { return 1.0f; } private int decode(String color, int i) { if (color.length() < 7) { String substring = color.substring(i + 1, i + 2); return Integer.parseInt(substring + substring, 16); } return Integer.parseInt(color.substring(i * 2 + 1, i * 2 + 3), 16); } private String encode(double red, double green, double blue) { return "#" + toHex(red) + toHex(green) + toHex(blue); } protected String toHex(double color) { String prefix = ""; int roundedColor = (int) Math.round(color); if (roundedColor < 16) prefix = "0"; return prefix + Integer.toHexString(roundedColor); } @Override @NotAstProperty public List<? extends ASTCssNode> getChilds() { return Collections.emptyList(); } @Override public ASTCssNodeType getType() { return ASTCssNodeType.COLOR_EXPRESSION; } @Override public String toString() { return "" + value; } @Override public ColorExpression clone() { return (ColorExpression) super.clone(); } public String toARGB() { return "#ff" + toHex(red) + toHex(green) + toHex(blue); } public Color toColor() { return new Color((int) Math.round(this.red), (int) Math.round(this.green), (int) Math.round(this.blue)); } public boolean hasAlpha() { return false; } public boolean isNamed() { return false; } public String getColorName() { return null; } public static class ColorWithAlphaExpression extends ColorExpression { /** * Alpha in the range 0-1. */ private double alpha; public ColorWithAlphaExpression(HiddenTokenAwareTree token, ColorExpression colorExpression) { super(token, colorExpression); alpha = colorExpression.getAlpha(); this.value = encode(red, green, blue, alpha); } public ColorWithAlphaExpression(HiddenTokenAwareTree token, double red, double green, double blue, double alpha) { super(token, red, green, blue); this.alpha = alpha; if (alpha != 1.0) { this.value = encode(red, green, blue, alpha); } } public ColorWithAlphaExpression(HiddenTokenAwareTree token, String originalValue, double red, double green, double blue, double alpha) { super(token, originalValue, red, green, blue); this.alpha = alpha; } @Override public double getAlpha() { return alpha; } protected String encode(double red, double green, double blue, double alpha) { return "rgba(" + roundFormat(red) + ", " + roundFormat(green) + ", " + roundFormat(blue) + ", " + roundFormatAlpha(alpha) + ")"; } //alpha colors do not have hexadecimal value for now @Override public String getValueInHexadecimal() { return getValue(); } private String roundFormat(double value) { return PrintUtils.formatNumber(Math.round(value)); } private String roundFormatAlpha(double value) { return PrintUtils.formatNumberTwoDecimal(Math.round(value*1000000)/1000000.0); } @Override public String toARGB() { return "#" + toHex(Math.round(alpha * 255)) + toHex(red) + toHex(green) + toHex(blue); } @Override public Color toColor() { return new Color((int) Math.round(this.red), (int) Math.round(this.green), (int) Math.round(this.blue), Math.round(this.alpha * 255)); } @Override public boolean hasAlpha() { return true; } } }