Skip to content

Commit 9caf421

Browse files
committed
redone HSL using CssValues instead of floats, see #201
1 parent 6fd58bf commit 9caf421

3 files changed

Lines changed: 112 additions & 38 deletions

File tree

org/w3c/css/values/CssAngle.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public final int getType() {
3737
return type;
3838
}
3939

40-
private static final BigDecimal deg360;
40+
protected static final BigDecimal deg360;
4141

4242
static {
4343
deg360 = BigDecimal.valueOf(360);
@@ -165,12 +165,21 @@ public boolean equals(Object value) {
165165
unit.equals(((CssAngle) value).unit));
166166
}
167167

168-
private BigDecimal normalize(BigDecimal degree) {
168+
private BigDecimal normalize(BigDecimal value) {
169+
BigDecimal degree = value.multiply(factor);
170+
if ((degree.compareTo(BigDecimal.ZERO) >= 0) && (degree.compareTo(deg360) <= 0)) {
171+
// no need to normalize
172+
return value;
173+
}
169174
degree = degree.remainder(deg360);
170175
if (degree.compareTo(BigDecimal.ZERO) < 0) {
171176
degree.add(deg360);
172177
}
173-
return degree;
178+
return degree.divide(factor, 9, BigDecimal.ROUND_HALF_DOWN).stripTrailingZeros();
179+
}
180+
181+
public void normalizeValue() {
182+
value = normalize(value);
174183
}
175184

176185
public CssAngle getAngle() {
@@ -180,7 +189,7 @@ public CssAngle getAngle() {
180189
//@@FIXME I should return the remainder for all ...
181190

182191
public float getDegree() {
183-
return normalize(value.multiply(factor)).floatValue();
192+
return normalize(value).floatValue();
184193
}
185194

186195
/**
@@ -189,7 +198,7 @@ public float getDegree() {
189198
* @return a boolean
190199
*/
191200
public boolean isPositive() {
192-
return (normalize(value).signum() >= 0);
201+
return (value.signum() >= 0);
193202
}
194203

195204
/**
@@ -198,7 +207,7 @@ public boolean isPositive() {
198207
* @return a boolean
199208
*/
200209
public boolean isStrictlyPositive() {
201-
return (normalize(value).signum() == 1);
210+
return (value.signum() == 1);
202211
}
203212

204213
/**

org/w3c/css/values/CssColor.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ private void __setRGBAColor(RGBA rgba, CssExpression exp, ApplContext ac)
463463
}
464464
switch (val.getType()) {
465465
case CssTypes.CSS_NUMBER:
466-
// starting with CSS Color 4, percentages are allowed
466+
// starting with CSS Color 4
467467
case CssTypes.CSS_PERCENTAGE:
468468
rgba.setAlpha(ac, val);
469469
break;
@@ -496,11 +496,13 @@ public void setHSLColor(CssExpression exp, ApplContext ac)
496496
if (val == null || op != COMMA) {
497497
throw new InvalidParamException("invalid-color", ac);
498498
}
499-
if (val.getType() == CssTypes.CSS_NUMBER) {
500-
CssNumber number = (CssNumber) val;
501-
hsl.setHue(angleValue(number.getValue(), ac));
502-
} else {
503-
throw new InvalidParamException("rgb", val, ac); // FIXME hsl
499+
switch (val.getType()) {
500+
case CssTypes.CSS_ANGLE:
501+
case CssTypes.CSS_NUMBER:
502+
hsl.setHue(ac, val);
503+
break;
504+
default:
505+
throw new InvalidParamException("rgb", val, ac); // FIXME hsl
504506
}
505507

506508
// S
@@ -511,9 +513,9 @@ public void setHSLColor(CssExpression exp, ApplContext ac)
511513
exp.starts();
512514
throw new InvalidParamException("invalid-color", ac);
513515
}
516+
// todo is (0 number) allowed ?
514517
if (val.getType() == CssTypes.CSS_PERCENTAGE) {
515-
CssPercentage percent = (CssPercentage) val;
516-
hsl.setSaturation(clippedPercentValue(percent.floatValue(), ac));
518+
hsl.setSaturation(ac, val);
517519
} else {
518520
exp.starts();
519521
throw new InvalidParamException("rgb", val, ac); // FIXME hsl
@@ -529,8 +531,7 @@ public void setHSLColor(CssExpression exp, ApplContext ac)
529531
}
530532

531533
if (val.getType() == CssTypes.CSS_PERCENTAGE) {
532-
CssPercentage percent = (CssPercentage) val;
533-
hsl.setLightness(clippedPercentValue(percent.floatValue(), ac));
534+
hsl.setLightness(ac, val);
534535
} else {
535536
exp.starts();
536537
throw new InvalidParamException("rgb", val, ac); // FIXME hsl

org/w3c/css/values/HSL.java

Lines changed: 86 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,42 +13,106 @@
1313
*/
1414
package org.w3c.css.values;
1515

16+
import org.w3c.css.util.ApplContext;
17+
import org.w3c.css.util.InvalidParamException;
1618
import org.w3c.css.util.Util;
1719

20+
import java.math.BigDecimal;
21+
1822
public class HSL {
1923
String output = null;
20-
float fh;
21-
float fs;
22-
float fl;
24+
CssValue vh, vs, vl;
2325

2426
/**
2527
* Create a new HSL
2628
*/
2729
public HSL() {
2830
}
2931

30-
public void setHue(float hue) {
31-
this.fh = (float) ((((double) hue % 360.0) + 360.0) % 360.0);
32-
}
33-
34-
public void setHue(CssNumber hue) {
35-
setHue(hue.getValue());
36-
}
37-
38-
public void setSaturation(float sat) {
39-
this.fs = sat;
32+
public final CssValue filterValue(ApplContext ac, CssValue val)
33+
throws InvalidParamException {
34+
output = null;
35+
if (val.getRawType() == CssTypes.CSS_CALC) {
36+
// TODO add warning about uncheckability
37+
// might need to extend...
38+
} else {
39+
if (val.getType() == CssTypes.CSS_PERCENTAGE) {
40+
CssCheckableValue v = val.getCheckableValue();
41+
if (!v.warnPositiveness(ac, "RGB")) {
42+
CssNumber nb = new CssNumber();
43+
nb.setIntValue(0);
44+
return nb;
45+
}
46+
if (val.getRawType() == CssTypes.CSS_PERCENTAGE) {
47+
float p = ((CssPercentage) val).floatValue();
48+
if (p > 100.) {
49+
ac.getFrame().addWarning("out-of-range", Util.displayFloat(p));
50+
return new CssPercentage(100);
51+
}
52+
}
53+
}
54+
}
55+
return val;
4056
}
4157

42-
public void setSaturation(CssNumber sat) {
43-
setSaturation(sat.getValue());
58+
public final void setHue(ApplContext ac, CssValue val)
59+
throws InvalidParamException {
60+
output = null;
61+
if (val.getRawType() == CssTypes.CSS_CALC) {
62+
// TODO add warning about uncheckability
63+
// might need to extend...
64+
} else {
65+
if (val.getType() == CssTypes.CSS_NUMBER) {
66+
// numbers are treated as degrees
67+
CssCheckableValue v = val.getCheckableValue();
68+
if (!v.isPositive()) {
69+
ac.getFrame().addWarning("out-of-range", val.toString());
70+
if (val.getRawType() == CssTypes.CSS_NUMBER) {
71+
float p = ((CssNumber) val).getValue();
72+
CssNumber nb = new CssNumber();
73+
nb.setFloatValue((float) ((((double) p % 360.0) + 360.0) % 360.0));
74+
vh = nb;
75+
return;
76+
}
77+
}
78+
if (val.getRawType() == CssTypes.CSS_NUMBER) {
79+
float p = ((CssNumber) val).getValue();
80+
if (p > 360.) {
81+
ac.getFrame().addWarning("out-of-range", Util.displayFloat(p));
82+
CssNumber nb = new CssNumber();
83+
nb.setFloatValue((float) ((((double) p % 360.0) + 360.0) % 360.0));
84+
vh = nb;
85+
return;
86+
}
87+
}
88+
} else if (val.getType() == CssTypes.CSS_ANGLE) {
89+
// since css-color-4
90+
CssCheckableValue v = val.getCheckableValue();
91+
if (!v.isPositive()) {
92+
ac.getFrame().addWarning("out-of-range", val.toString());
93+
}
94+
if (val.getRawType() == CssTypes.CSS_ANGLE) {
95+
CssAngle a = (CssAngle) val;
96+
float p = a.getValue();
97+
if (p > a.deg360.divide(a.factor, 2, BigDecimal.ROUND_HALF_DOWN).floatValue()) {
98+
ac.getFrame().addWarning("out-of-range", Util.displayFloat(p));
99+
}
100+
// if a proper angle we normalize it after checking everything.
101+
a.normalizeValue();
102+
}
103+
}
104+
}
105+
vh = val;
44106
}
45107

46-
public void setLightness(float light) {
47-
this.fl = light;
108+
public final void setSaturation(ApplContext ac, CssValue val)
109+
throws InvalidParamException {
110+
vs = filterValue(ac, val);
48111
}
49112

50-
public void setLightness(CssNumber light) {
51-
setLightness(light.getValue());
113+
public final void setLightness(ApplContext ac, CssValue val)
114+
throws InvalidParamException {
115+
vl = filterValue(ac, val);
52116
}
53117

54118
/**
@@ -57,9 +121,9 @@ public void setLightness(CssNumber light) {
57121
public String toString() {
58122
if (output == null) {
59123
StringBuilder sb = new StringBuilder("hsl(");
60-
sb.append(Util.displayFloat(fh)).append(", ");
61-
sb.append(Util.displayFloat(fs)).append("%, ");
62-
sb.append(Util.displayFloat(fl)).append("%)");
124+
sb.append(vh).append(", ");
125+
sb.append(vs).append(", ");
126+
sb.append(vl).append(")");
63127
output = sb.toString();
64128
}
65129
return output;

0 commit comments

Comments
 (0)