Skip to content

Commit

Permalink
css: make css constants non-modifiable, bridge: use float color compo…
Browse files Browse the repository at this point in the history
…nents
  • Loading branch information
carlosame committed Aug 20, 2024
1 parent ce3439a commit 3edd5b8
Show file tree
Hide file tree
Showing 14 changed files with 1,040 additions and 652 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -520,11 +520,11 @@ public static Color convertDeviceColor(Element e, Value srgb, DeviceColor c, flo
}
Color cmyk = new ColorWithAlternatives(cmykCs, comps, opacity, null);
RGBColorValue rgb = (RGBColorValue) color;
int r = resolveColorComponent(rgb.getR());
int g = resolveColorComponent(rgb.getG());
int b = resolveColorComponent(rgb.getB());
float r = resolveColorComponent(rgb.getR());
float g = resolveColorComponent(rgb.getG());
float b = resolveColorComponent(rgb.getB());
float a = resolveAlphaComponent(c.getAlpha());
Color specColor = new ColorWithAlternatives(r, g, b, Math.round(a * opacity * 255f),
Color specColor = new ColorWithAlternatives(r, g, b, a * opacity,
new Color[] { cmyk });
return specColor;
} else {
Expand Down Expand Up @@ -560,11 +560,11 @@ public static Color convertColor(ColorValue c, float opacity, BridgeContext ctx)
* @param opacity The opacity value (0 <= o <= 1).
*/
public static Color convertColor(RGBColorValue c, float opacity) {
int r = resolveColorComponent(c.getR());
int g = resolveColorComponent(c.getG());
int b = resolveColorComponent(c.getB());
float r = resolveColorComponent(c.getR());
float g = resolveColorComponent(c.getG());
float b = resolveColorComponent(c.getB());
float a = resolveAlphaComponent(c.getAlpha());
return new Color(r, g, b, Math.round(a * opacity * 255f));
return new Color(r, g, b, a * opacity);
}

/**
Expand Down Expand Up @@ -603,9 +603,9 @@ public static Color convertColor(ColorFunction c, float opacity, BridgeContext c
case ColorValue.CS_XYZ_D65:
CSSStyleValueList<NumericValue> chs = c.getChannels();
float[] ch = new float[3];
ch[0] = resolveColorFunctionComponent(chs.item(0));
ch[1] = resolveColorFunctionComponent(chs.item(1));
ch[2] = resolveColorFunctionComponent(chs.item(2));
ch[0] = resolveColorComponent(chs.item(0));
ch[1] = resolveColorComponent(chs.item(1));
ch[2] = resolveColorComponent(chs.item(2));
float[] xyzd50 = d65xyzToD50(ch);
float a = resolveAlphaComponent(c.getAlpha());
cs = ColorSpace.getInstance(ColorSpace.CS_CIEXYZ);
Expand All @@ -628,27 +628,40 @@ public static Color convertColor(ColorFunction c, float opacity, BridgeContext c
}
}

/////////////////////////////////////////////////////////////////////////
// Color utility methods
/////////////////////////////////////////////////////////////////////////

private static Color convert3Color(ColorSpace space, ColorFunction c, float opacity) {
CSSStyleValueList<NumericValue> chs = c.getChannels();
float[] ch = new float[3];
ch[0] = resolveColorFunctionComponent(chs.item(0));
ch[1] = resolveColorFunctionComponent(chs.item(1));
ch[2] = resolveColorFunctionComponent(chs.item(2));
ch[0] = resolveColorComponent(chs.item(0));
ch[1] = resolveColorComponent(chs.item(1));
ch[2] = resolveColorComponent(chs.item(2));
float a = resolveAlphaComponent(c.getAlpha());
return new Color(space, ch, a * opacity);
}

private static float resolveColorFunctionComponent(NumericValue item) {
float f = item.getFloatValue();
/**
* Returns the value of one color component (0 &lt;= result &lt;= 1).
*
* @param v the value that declares the color component, either a percentage or
* a number in the range (0 &lt;= v &lt;= 1).
* @return the value in the range (0 &lt;= v &lt;= 1).
*/
private static float resolveColorComponent(NumericValue item) {
float f;
switch (item.getCSSUnit()) {
case CSSUnit.CSS_NUMBER:
f = item.getFloatValue();
if (f < 0f) {
f = 0f;
} else if (f > 1f) {
f = 1f;
}
return f;
case CSSUnit.CSS_PERCENTAGE:
f = item.getFloatValue();
if (f < 0f) {
f = 0f;
} else if (f > 100f) {
Expand Down Expand Up @@ -809,26 +822,12 @@ public static int convertStrokeLinejoin(Value v) {
/////////////////////////////////////////////////////////////////////////

/**
* Returns the value of one color component (0 &lt;= result &lt;= 255).
* Returns the value of the alpha component (0 &lt;= result &lt;= 1).
*
* @param v the value that defines the color component
* @param v the value that declares the alpha component, either a percentage or
* a number in the range (0 &lt;= v &lt;= 1).
* @return the value in the range (0 &lt;= v &lt;= 1).
*/
public static int resolveColorComponent(Value v) {
float f;
switch (v.getCSSUnit()) {
case CSSUnit.CSS_PERCENTAGE:
f = v.getFloatValue();
f = (f > 100f) ? 100f : (f < 0f) ? 0f : f;
return Math.round(255f * f / 100f);
case CSSUnit.CSS_NUMBER:
f = v.getFloatValue();
f = (f > 255f) ? 255f : (f < 0f) ? 0f : f;
return Math.round(f);
default:
throw new IllegalArgumentException("Color component argument is not an appropriate CSS value");
}
}

private static float resolveAlphaComponent(Value v) {
float f;
switch (v.getCSSUnit()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@
import java.util.Locale;
import java.util.Map;

import org.w3c.css.om.unit.CSSUnit;

import io.sf.carte.echosvg.css.engine.value.FloatValue;
import io.sf.carte.echosvg.css.engine.value.RGBColorValue;
import io.sf.carte.echosvg.css.engine.value.Value;
import io.sf.carte.echosvg.util.CSSConstants;
Expand All @@ -48,9 +45,7 @@ public class SystemColorSupport implements CSSConstants {
public static Value getSystemColor(String ident) {
ident = ident.toLowerCase(Locale.ROOT);
SystemColor sc = factories.get(ident);
return new RGBColorValue(new FloatValue(CSSUnit.CSS_NUMBER, sc.getRed()),
new FloatValue(CSSUnit.CSS_NUMBER, sc.getGreen()),
new FloatValue(CSSUnit.CSS_NUMBER, sc.getBlue()));
return new RGBColorValue(sc.getComponents(null));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public AbstractValue clone() {
try {
return (AbstractValue) super.clone();
} catch (CloneNotSupportedException e) {
return null;
throw new IllegalStateException(e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ protected ColorValue() {
*/
protected ColorValue(NumericValue a) throws DOMSyntaxException {
super();
setAlpha(a);
setAlphaChannel(a);
}

/**
Expand Down Expand Up @@ -129,6 +129,10 @@ public void setAlpha(double alpha) {
* @throws DOMSyntaxException if alpha is not a percentage.
*/
public void setAlpha(CSSNumericValue alpha) throws DOMSyntaxException {
setAlphaChannel(alpha);
}

private void setAlphaChannel(CSSNumericValue alpha) throws DOMSyntaxException {
NumericValue a = (NumericValue) alpha;
if (a.getCSSUnit() != CSSUnit.CSS_PERCENTAGE && a.getCSSUnit() != CSSUnit.CSS_NUMBER) {
throw new DOMSyntaxException("Alpha channel must be a number or percentage.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,20 @@ public static String getCssText(short unit, float value) {
return s + CSSUnit.dimensionUnitString(unit);
}

/**
* Create a constant with the given unit and value.
* <p>
* If you want to have a modifiable copy of the returned value, clone it.
* </p>
*
* @param unit the unit.
* @param value the value expressed in that unit.
* @return the immutable value.
*/
public static FloatValue createConstant(short unit, float value) {
return new ImmutableUnitValue(unit, value);
}

/**
* The float value
*/
Expand All @@ -68,6 +82,9 @@ public static String getCssText(short unit, float value) {

/**
* Creates a new value.
*
* @param unit the unit.
* @param value the value expressed in that unit.
*/
public FloatValue(short unitType, float floatValue) {
this.unitType = unitType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,19 @@ public IdentValue(String s) {
super(s);
}

/**
* Creates a constant identifier.
* <p>
* If you want to have a modifiable copy of the returned value, clone it.
* </p>
*
* @param s the identifier.
* @return an immutable identifier value.
*/
public static IdentValue createConstant(String s) {
return new ImmutableIdentValue(s);
}

/**
* The type of the value.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
See the NOTICE file distributed with this work for additional
information regarding copyright ownership.
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 io.sf.carte.echosvg.css.engine.value;

import org.w3c.api.DOMTypeException;
import org.w3c.dom.DOMException;

/**
* Immutable identifier values.
*
* @author See Git history.
* @version $Id$
*/
class ImmutableIdentValue extends IdentValue {

/**
* Creates a new immutable IdentValue.
*/
public ImmutableIdentValue(String s) {
super(s);
}

@Override
public void setValue(String value) throws DOMTypeException {
throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, "Immutable value.");
}

@Override
public IdentValue clone() {
return new IdentValue(value);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
See the NOTICE file distributed with this work for additional
information regarding copyright ownership.
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 io.sf.carte.echosvg.css.engine.value;

import org.w3c.api.DOMSyntaxException;
import org.w3c.css.om.typed.CSSNumericValue;
import org.w3c.dom.DOMException;

/**
* Immutable RGB colors.
*
* @author See Git history.
* @version $Id$
*/
class ImmutableRGBColorValue extends RGBColorValue {

/**
* Creates a new, opaque RGBColorValue.
*
* @throws DOMSyntaxException if a supplied component is invalid.
*/
public ImmutableRGBColorValue(NumericValue r, NumericValue g, NumericValue b)
throws DOMSyntaxException {
super(r, g, b);
}

/**
* Creates a new RGBColorValue.
*
* @throws DOMSyntaxException if a supplied component is invalid.
*/
public ImmutableRGBColorValue(NumericValue r, NumericValue g, NumericValue b, NumericValue a)
throws DOMSyntaxException {
super(r, g, b, a);
}

@Override
void setRGB(NumericValue r, NumericValue g, NumericValue b) {
red = r;
green = g;
blue = b;
}

@Override
public void setR(double r) {
immutable();
}

private void immutable() {
throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, "Immutable value.");
}

@Override
public void setR(CSSNumericValue r) throws DOMSyntaxException {
immutable();
}

@Override
public void setG(double g) {
immutable();
}

@Override
public void setG(CSSNumericValue g) throws DOMSyntaxException {
immutable();
}

@Override
public void setB(double b) {
immutable();
}

@Override
public void setB(CSSNumericValue b) throws DOMSyntaxException {
immutable();
}

@Override
public RGBColorValue clone() {
RGBColorValue clon;
try {
clon = new RGBColorValue(getR().clone(), getG().clone(), getB().clone(), getAlpha().clone());
} catch (DOMSyntaxException e) {
throw new IllegalStateException(e);
}
return clon;
}

}
Loading

0 comments on commit 3edd5b8

Please sign in to comment.