Skip to content

Commit

Permalink
Upgrade to css4j 4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosame committed Mar 30, 2023
1 parent 1b46412 commit f019e31
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 55 deletions.
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ description = 'css4j-awt'
dependencies {
api('io.sf.carte:css4j') {
version {
strictly '[3.4.0,)'
prefer '3.9.1'
strictly '[4.0,)'
prefer '4.0'
}
}
testImplementation group: 'io.sf.carte', name: 'css4j', classifier: 'tests', version: '3.9.1'
testImplementation group: 'io.sf.carte', name: 'css4j', classifier: 'tests', version: '4.0'
testImplementation 'io.sf.carte:xml-dtd:4.1.1'
testImplementation 'nu.validator:htmlparser:1.4.16'
testImplementation 'org.slf4j:slf4j-api:2.0.6'
Expand Down
36 changes: 36 additions & 0 deletions junit/io/sf/carte/doc/style/css/awt/AWTHelperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,42 @@ public void testGetAWTColor() throws CSSPropertyValueException {
assertEquals(0, color.getBlue());
assertEquals(255, color.getAlpha());
//
style.setCssText("color: lch(32.67 12.93 244.59)");
cssColor = style.getPropertyCSSValue("color");
assertNotNull(cssColor);
assertEquals(CssType.TYPED, cssColor.getCssValueType());
assertEquals(CSSValue.Type.COLOR, ((CSSTypedValue) cssColor).getPrimitiveType());
color = AWTHelper.getAWTColor((CSSTypedValue) cssColor);
assertNotNull(color);
assertEquals(58, color.getRed());
assertEquals(80, color.getGreen());
assertEquals(95, color.getBlue());
assertEquals(255, color.getAlpha());
//
style.setCssText("color: color(display-p3 0.253 0.1087 0.7796/0.8)");
cssColor = style.getPropertyCSSValue("color");
assertNotNull(cssColor);
assertEquals(CssType.TYPED, cssColor.getCssValueType());
assertEquals(CSSValue.Type.COLOR, ((CSSTypedValue) cssColor).getPrimitiveType());
color = AWTHelper.getAWTColor((CSSTypedValue) cssColor);
assertNotNull(color);
assertEquals(70, color.getRed());
assertEquals(25, color.getGreen());
assertEquals(207, color.getBlue());
assertEquals(204, color.getAlpha());
//
style.setCssText("color: sandybrown");
cssColor = style.getPropertyCSSValue("color");
assertNotNull(cssColor);
assertEquals(CssType.TYPED, cssColor.getCssValueType());
assertEquals(CSSValue.Type.IDENT, ((CSSTypedValue) cssColor).getPrimitiveType());
color = AWTHelper.getAWTColor((CSSTypedValue) cssColor);
assertNotNull(color);
assertEquals(244, color.getRed());
assertEquals(164, color.getGreen());
assertEquals(96, color.getBlue());
assertEquals(255, color.getAlpha());
//
style.setCssText("color: transparent; ");
cssColor = style.getPropertyCSSValue("color");
assertNotNull(cssColor);
Expand Down
112 changes: 60 additions & 52 deletions src/io/sf/carte/doc/style/css/awt/AWTHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@
import java.util.HashMap;
import java.util.Map;

import org.w3c.dom.DOMException;

import io.sf.carte.doc.style.css.CSSComputedProperties;
import io.sf.carte.doc.style.css.CSSPrimitiveValue;
import io.sf.carte.doc.style.css.CSSTypedValue;
import io.sf.carte.doc.style.css.CSSUnit;
import io.sf.carte.doc.style.css.CSSValue.CssType;
import io.sf.carte.doc.style.css.CSSValue.Type;
import io.sf.carte.doc.style.css.RGBAColor;
import io.sf.carte.doc.style.css.property.CSSPropertyValueException;
import io.sf.carte.doc.style.css.property.ColorIdentifiers;

/**
* AWT helper methods.
Expand Down Expand Up @@ -86,61 +88,53 @@ public static Font createFont(CSSComputedProperties computedStyle) {
* number or an identifier.
* @return the AWT color object, or null if the color was specified as an
* unknown identifier.
* @throws CSSPropertyValueException if the color declaration is malformed or a
* color identifier is unknown.
* @throws CSSPropertyValueException if a color cannot be derived from the CSS
* value.
*/
public static Color getAWTColor(CSSTypedValue cssColor) throws CSSPropertyValueException {
Color awtcolor = null;
if (cssColor != null) {
switch (cssColor.getPrimitiveType()) {
case COLOR:
RGBAColor color = cssColor.toRGBColor();
CSSPrimitiveValue red = color.getRed();
CSSPrimitiveValue green = color.getGreen();
CSSPrimitiveValue blue = color.getBlue();
CSSPrimitiveValue prialpha = color.getAlpha();
//
if (red.getCssValueType() != CssType.TYPED || green.getCssValueType() != CssType.TYPED
|| blue.getCssValueType() != CssType.TYPED || prialpha.getCssValueType() != CssType.TYPED) {
CSSPropertyValueException ex = new CSSPropertyValueException("Unknown color.");
case IDENT:
RGBAColor color;
try {
color = cssColor.toRGBColor();
} catch (RuntimeException e) {
CSSPropertyValueException ex = new CSSPropertyValueException(
"Cannot obtain a RGB color.", e);
ex.setValueText(cssColor.getCssText());
throw ex;
}
float alpha = ((CSSTypedValue) prialpha).getFloatValue(CSSUnit.CSS_NUMBER);
switch (red.getUnitType()) {
case CSSUnit.CSS_PERCENTAGE:
awtcolor = new Color(clipColorValue(((CSSTypedValue) red).getFloatValue(CSSUnit.CSS_PERCENTAGE) / 100f),
clipColorValue(((CSSTypedValue) green).getFloatValue(CSSUnit.CSS_PERCENTAGE) / 100f),
clipColorValue(((CSSTypedValue) blue).getFloatValue(CSSUnit.CSS_PERCENTAGE) / 100f), alpha);
break;
case CSSUnit.CSS_NUMBER:
try {
awtcolor = new Color(clipColorValue((int) ((CSSTypedValue) red).getFloatValue(CSSUnit.CSS_NUMBER)),
clipColorValue((int) ((CSSTypedValue) green).getFloatValue(CSSUnit.CSS_NUMBER)),
clipColorValue((int) ((CSSTypedValue) blue).getFloatValue(CSSUnit.CSS_NUMBER)),
Math.round(alpha * 255f));
} catch (IllegalArgumentException e) {
CSSPropertyValueException ex = new CSSPropertyValueException("Unknown color.", e);
ex.setValueText(cssColor.getCssText());
throw ex;
}

double[] rgb;
try {
rgb = color.toNumberArray();
} catch (RuntimeException e) {
CSSPropertyValueException ex = new CSSPropertyValueException(
"Cannot obtain the color components.", e);
ex.setValueText(cssColor.getCssText());
throw ex;
}
break;
case IDENT:
String sv = cssColor.getStringValue();
String s = ColorIdentifiers.getInstance().getColor(sv);
if (s != null) {
try {
awtcolor = Color.decode(s);
} catch (NumberFormatException e) {
CSSPropertyValueException ex = new CSSPropertyValueException("Unknown color", e);
ex.setValueText(sv);
throw ex;
}
} else if ("transparent".equals(sv)) {
return new Color(0, 0, 0, 0);
} else {
return Color.getColor(sv);

CSSPrimitiveValue prialpha = color.getAlpha();

if (prialpha.getCssValueType() != CssType.TYPED) {
CSSPropertyValueException ex = new CSSPropertyValueException(
"Unsupported alpha channel.");
ex.setValueText(cssColor.getCssText());
throw ex;
}

float alpha = normalizedAlphaComponent((CSSTypedValue) prialpha);

try {
awtcolor = new Color((float) rgb[0], (float) rgb[1], (float) rgb[2], alpha);
} catch (IllegalArgumentException e) {
CSSPropertyValueException ex = new CSSPropertyValueException("Unknown color.",
e);
ex.setValueText(cssColor.getCssText());
throw ex;
}
break;
case NUMERIC:
Expand All @@ -156,12 +150,26 @@ public static Color getAWTColor(CSSTypedValue cssColor) throws CSSPropertyValueE
return awtcolor;
}

static int clipColorValue(int color) {
return Math.max(Math.min(255, color), 0);
}

static float clipColorValue(float color) {
return Math.max(Math.min(1f, color), 0f);
/**
* Normalize the alpha component to a [0,1] interval.
*
* @param typed the component.
* @return the normalized component.
*/
private static float normalizedAlphaComponent(CSSTypedValue typed) {
float comp;
short unit = typed.getUnitType();
if (unit == CSSUnit.CSS_PERCENTAGE) {
comp = typed.getFloatValue(CSSUnit.CSS_PERCENTAGE) * 0.01f;
} else if (unit == CSSUnit.CSS_NUMBER) {
comp = typed.getFloatValue(CSSUnit.CSS_NUMBER);
} else if (typed.getPrimitiveType() == Type.IDENT) {
comp = 0f;
} else {
throw new DOMException(DOMException.TYPE_MISMATCH_ERR,
"Wrong component: " + typed.getCssText());
}
return Math.max(Math.min(1f, comp), 0f);
}

}

0 comments on commit f019e31

Please sign in to comment.