diff --git a/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGAnimationEngine.java b/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGAnimationEngine.java
index cc91c3b18..48ba03649 100644
--- a/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGAnimationEngine.java
+++ b/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGAnimationEngine.java
@@ -29,6 +29,7 @@
import java.util.Set;
import org.w3c.css.om.unit.CSSUnit;
+import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.css.CSSStyleDeclaration;
@@ -37,6 +38,7 @@
import org.w3c.dom.svg.SVGLength;
import org.w3c.dom.svg.SVGPreserveAspectRatio;
+import io.sf.carte.doc.style.css.property.NumberValue;
import io.sf.carte.echosvg.anim.AnimationEngine;
import io.sf.carte.echosvg.anim.AnimationException;
import io.sf.carte.echosvg.anim.dom.AnimationTarget;
@@ -1815,8 +1817,14 @@ protected AnimatableValue createAnimatableValue(AnimationTarget target, String p
unit = SVGAngle.SVG_ANGLETYPE_GRAD;
break;
default:
- // XXX Do something better than returning null.
- return null;
+ try {
+ float f = NumberValue.floatValueConversion(v.getFloatValue(), v.getCSSUnit(),
+ CSSUnit.CSS_DEG);
+ return new AnimatableAngleOrIdentValue(target, f, SVGAngle.SVG_ANGLETYPE_DEG);
+ } catch (DOMException e) {
+ // XXX Do something better than returning null.
+ return null;
+ }
}
return new AnimatableAngleValue(target, v.getFloatValue(), unit);
}
@@ -1846,8 +1854,14 @@ protected AnimatableValue createAnimatableValue(AnimationTarget target, String p
unit = SVGAngle.SVG_ANGLETYPE_GRAD;
break;
default:
- // XXX Do something better than returning null.
- return null;
+ try {
+ float f = NumberValue.floatValueConversion(v.getFloatValue(), v.getCSSUnit(),
+ CSSUnit.CSS_DEG);
+ return new AnimatableAngleOrIdentValue(target, f, SVGAngle.SVG_ANGLETYPE_DEG);
+ } catch (DOMException e) {
+ // XXX Do something better than returning null.
+ return null;
+ }
}
return new AnimatableAngleOrIdentValue(target, v.getFloatValue(), unit);
}
diff --git a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/dom/CSSOMValue.java b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/dom/CSSOMValue.java
index 03d08efef..fe3109d44 100644
--- a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/dom/CSSOMValue.java
+++ b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/dom/CSSOMValue.java
@@ -22,6 +22,7 @@
import org.w3c.css.om.unit.CSSUnit;
import org.w3c.dom.DOMException;
+import io.sf.carte.doc.style.css.property.NumberValue;
import io.sf.carte.echosvg.css.engine.value.ColorValue;
import io.sf.carte.echosvg.css.engine.value.RectValue;
import io.sf.carte.echosvg.css.engine.value.Value;
@@ -108,16 +109,24 @@ public float getFloatValue() throws DOMException {
* Converts the actual float value to the given unit type.
*/
public static float convertFloatValue(short unitType, Value value) {
+ if (value.getCSSUnit() == unitType) {
+ return value.getFloatValue();
+ }
switch (unitType) {
case CSSUnit.CSS_NUMBER:
case CSSUnit.CSS_PERCENTAGE:
case CSSUnit.CSS_EM:
case CSSUnit.CSS_EX:
- case CSSUnit.CSS_OTHER:
case CSSUnit.CSS_PX:
- if (value.getCSSUnit() == unitType) {
- return value.getFloatValue();
- }
+ case CSSUnit.CSS_REM:
+ case CSSUnit.CSS_REX:
+ case CSSUnit.CSS_LH:
+ case CSSUnit.CSS_RLH:
+ case CSSUnit.CSS_VW:
+ case CSSUnit.CSS_VH:
+ case CSSUnit.CSS_VMIN:
+ case CSSUnit.CSS_VMAX:
+ case CSSUnit.CSS_OTHER:
break;
case CSSUnit.CSS_CM:
return toCentimeters(value);
@@ -143,6 +152,9 @@ public static float convertFloatValue(short unitType, Value value) {
return toHertz(value);
case CSSUnit.CSS_KHZ:
return tokHertz(value);
+ default:
+ return NumberValue.floatValueConversion(value.getFloatValue(), value.getCSSUnit(),
+ unitType);
}
throw new DOMException(DOMException.INVALID_ACCESS_ERR, "");
}
diff --git a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/dom/CSSValue.java b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/dom/CSSValue.java
index fd021a246..c7471969b 100644
--- a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/dom/CSSValue.java
+++ b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/dom/CSSValue.java
@@ -21,9 +21,9 @@
import org.w3c.css.om.typed.CSSKeywordValue;
import org.w3c.css.om.typed.CSSStringValue;
import org.w3c.css.om.typed.CSSStyleValue;
+import org.w3c.css.om.unit.CSSUnit;
import org.w3c.dom.DOMException;
-import org.w3c.css.om.unit.CSSUnit;
import io.sf.carte.doc.style.css.property.KeywordValue;
import io.sf.carte.echosvg.css.engine.value.ListValue;
import io.sf.carte.echosvg.css.engine.value.NumericValue;
diff --git a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/CSSEngine.java b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/CSSEngine.java
index 386b621b6..bba9949bd 100644
--- a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/CSSEngine.java
+++ b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/CSSEngine.java
@@ -1249,9 +1249,9 @@ protected void parseStyleSheet(StyleSheet ss, InputSource is, ParsedURL uri) thr
/**
* Puts an author property from a style-map in another style-map, if possible.
*/
- protected void putAuthorProperty(StyleMap dest, int idx, Value sval, boolean imp, short origin) {
+ protected void putAuthorProperty(StyleMap dest, int idx, Value sval, boolean imp, int origin) {
Value dval = dest.getValue(idx);
- short dorg = dest.getOrigin(idx);
+ int dorg = dest.getOrigin(idx);
boolean dimp = dest.isImportant(idx);
boolean cond = dval == null;
@@ -1313,7 +1313,7 @@ protected void addMatchingRules(List rules, StyleSheet ss, SelectorMatcher
/**
* Adds the rules contained in the given list to a stylemap.
*/
- protected void addRules(SelectorMatcher matcher, StyleMap sm, ArrayList rules, short origin) {
+ protected void addRules(SelectorMatcher matcher, StyleMap sm, ArrayList rules, int origin) {
sortRules(rules, matcher);
if (origin == StyleMap.AUTHOR_ORIGIN) {
@@ -2007,7 +2007,7 @@ protected void inlineStyleAttributeUpdated(CSSStylableElement elt, StyleMap styl
// come from the inline style attribute or override style.
for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
if (style.isComputed(i) && !updated[i]) {
- short origin = style.getOrigin(i);
+ int origin = style.getOrigin(i);
if (origin >= StyleMap.INLINE_AUTHOR_ORIGIN) { // ToDo Jlint says: always same result ??
removed = true;
updated[i] = true;
@@ -2024,12 +2024,14 @@ protected void inlineStyleAttributeUpdated(CSSStylableElement elt, StyleMap styl
boolean fs = (fontSizeIndex == -1) ? false : updated[fontSizeIndex];
boolean lh = (lineHeightIndex == -1) ? false : updated[lineHeightIndex];
boolean cl = (colorIndex == -1) ? false : updated[colorIndex];
+ boolean isRoot = elt.getOwnerDocument().getDocumentElement() == elt;
for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
if (updated[i]) {
count++;
} else if ((fs && style.isFontSizeRelative(i)) || (lh && style.isLineHeightRelative(i))
- || (cl && style.isColorRelative(i))) {
+ || (cl && style.isColorRelative(i)) || (fs && isRoot && style.isRootFontSizeRelative(i))
+ || (lh && isRoot && style.isRootLineHeightRelative(i))) {
updated[i] = true;
clearComputedValue(style, i);
count++;
@@ -2170,13 +2172,14 @@ protected void propagateChanges(Node node, int[] props, boolean recascade) {
boolean fs = (fontSizeIndex == -1) ? false : updated[fontSizeIndex];
boolean lh = (lineHeightIndex == -1) ? false : updated[lineHeightIndex];
boolean cl = (colorIndex == -1) ? false : updated[colorIndex];
+ boolean isRootFs = fs && elt.getOwnerDocument().getDocumentElement() == elt;
int count = 0;
for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
if (updated[i]) {
count++;
} else if ((fs && style.isFontSizeRelative(i)) || (lh && style.isLineHeightRelative(i))
- || (cl && style.isColorRelative(i))) {
+ || (cl && style.isColorRelative(i)) || (isRootFs && style.isRootFontSizeRelative(i))) {
updated[i] = true;
clearComputedValue(style, i);
count++;
@@ -2265,7 +2268,7 @@ public void property(String name, LexicalUnit value, boolean important) {
updatedProperties[i] = true;
Value v = valueManagers[i].createValue(value, CSSEngine.this);
- styleMap.putMask(i, (short) 0);
+ styleMap.putMask(i, 0);
styleMap.putValue(i, v);
styleMap.putOrigin(i, StyleMap.INLINE_AUTHOR_ORIGIN);
}
@@ -2300,7 +2303,7 @@ protected void nonCSSPresentationalHintUpdated(CSSStylableElement elt, StyleMap
lu = parser.parsePropertyValue(new StringReader(newValue));
ValueManager vm = valueManagers[idx];
Value v = vm.createValue(lu, CSSEngine.this);
- style.putMask(idx, (short) 0);
+ style.putMask(idx, 0);
style.putValue(idx, v);
style.putOrigin(idx, StyleMap.NON_CSS_ORIGIN);
} catch (Exception e) {
@@ -2338,13 +2341,14 @@ protected void nonCSSPresentationalHintUpdated(CSSStylableElement elt, StyleMap
boolean fs = idx == fontSizeIndex;
boolean lh = idx == lineHeightIndex;
boolean cl = idx == colorIndex;
+ boolean isRootFs = fs && elt.getOwnerDocument().getDocumentElement() == elt;
int count = 0;
for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
if (updated[i]) {
count++;
} else if ((fs && style.isFontSizeRelative(i)) || (lh && style.isLineHeightRelative(i))
- || (cl && style.isColorRelative(i))) {
+ || (cl && style.isColorRelative(i)) || (isRootFs && style.isRootFontSizeRelative(i))) {
updated[i] = true;
clearComputedValue(style, i);
count++;
diff --git a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/StyleMap.java b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/StyleMap.java
index a77c1ac32..634ae5a8f 100644
--- a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/StyleMap.java
+++ b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/StyleMap.java
@@ -29,34 +29,33 @@
*/
public class StyleMap {
- //
- // The masks, still have 2 free bits: 0x0800, & 0x1000, could also
- // go to int if needed.
- //
- public static final short IMPORTANT_MASK = 0x0001;
- public static final short COMPUTED_MASK = 0x0002;
- public static final short NULL_CASCADED_MASK = 0x0004;
- public static final short INHERITED_MASK = 0x0008;
-
- public static final short LINE_HEIGHT_RELATIVE_MASK = 0x0010;
- public static final short FONT_SIZE_RELATIVE_MASK = 0x0020;
- public static final short COLOR_RELATIVE_MASK = 0x0040;
- public static final short PARENT_RELATIVE_MASK = 0x0080;
- public static final short BLOCK_WIDTH_RELATIVE_MASK = 0x0100;
- public static final short BLOCK_HEIGHT_RELATIVE_MASK = 0x0200;
- public static final short BOX_RELATIVE_MASK = 0x0400;
-
- public static final short ORIGIN_MASK = (short) 0xE000; // 3 last bits
+ public static final int IMPORTANT_MASK = 0x0001;
+ public static final int COMPUTED_MASK = 0x0002;
+ public static final int NULL_CASCADED_MASK = 0x0004;
+ public static final int INHERITED_MASK = 0x0008;
+
+ public static final int LINE_HEIGHT_RELATIVE_MASK = 0x0010;
+ public static final int FONT_SIZE_RELATIVE_MASK = 0x0020;
+ public static final int COLOR_RELATIVE_MASK = 0x0040;
+ public static final int PARENT_RELATIVE_MASK = 0x0080;
+ public static final int BLOCK_WIDTH_RELATIVE_MASK = 0x0100;
+ public static final int BLOCK_HEIGHT_RELATIVE_MASK = 0x0200;
+ public static final int BOX_RELATIVE_MASK = 0x0400;
+ public static final int ROOT_LINE_HEIGHT_RELATIVE_MASK = 0x0800;
+ public static final int ROOT_FONT_SIZE_RELATIVE_MASK = 0x1000;
+ public static final int VIEWPORT_RELATIVE_MASK = 0x2000;
+
+ public static final int ORIGIN_MASK = 0xE0000000; // 3 last bits
//
// The origin values.
//
- public static final short USER_AGENT_ORIGIN = 0;
- public static final short USER_ORIGIN = 0x2000; // 0010
- public static final short NON_CSS_ORIGIN = 0x4000; // 0100
- public static final short AUTHOR_ORIGIN = 0x6000; // 0110
- public static final short INLINE_AUTHOR_ORIGIN = (short) 0x8000; // 1000
- public static final short OVERRIDE_ORIGIN = (short) 0xA000; // 1010
+ public static final int USER_AGENT_ORIGIN = 0;
+ public static final int USER_ORIGIN = 0x20000000; // 0010
+ public static final int NON_CSS_ORIGIN = 0x40000000; // 0100
+ public static final int AUTHOR_ORIGIN = 0x60000000; // 0110
+ public static final int INLINE_AUTHOR_ORIGIN = 0x80000000; // 1000
+ public static final int OVERRIDE_ORIGIN = 0xA0000000; // 1010
/**
* The values.
@@ -66,7 +65,7 @@ public class StyleMap {
/**
* To store the value masks.
*/
- protected short[] masks;
+ protected int[] masks;
/**
* Whether the values of this map cannot be re-cascaded.
@@ -78,7 +77,7 @@ public class StyleMap {
*/
public StyleMap(int size) {
values = new Value[size];
- masks = new short[size];
+ masks = new int[size];
}
/**
@@ -105,7 +104,7 @@ public Value getValue(int i) {
/**
* Returns the mask of the given property value.
*/
- public short getMask(int i) {
+ public int getMask(int i) {
return masks[i];
}
@@ -141,8 +140,8 @@ public boolean isInherited(int i) {
/**
* Returns the origin value.
*/
- public short getOrigin(int i) {
- return (short) (masks[i] & ORIGIN_MASK);
+ public int getOrigin(int i) {
+ return (masks[i] & ORIGIN_MASK);
}
/**
@@ -174,6 +173,22 @@ public boolean isFontSizeRelative(int i) {
return (masks[i] & FONT_SIZE_RELATIVE_MASK) != 0;
}
+ /**
+ * Tells whether the given property value is relative to 'line-height' of the
+ * {@code :root} element.
+ */
+ public boolean isRootLineHeightRelative(int i) {
+ return (masks[i] & ROOT_LINE_HEIGHT_RELATIVE_MASK) != 0;
+ }
+
+ /**
+ * Tells whether the given property value is relative to 'font-size' of the
+ * {@code :root} element.
+ */
+ public boolean isRootFontSizeRelative(int i) {
+ return (masks[i] & ROOT_FONT_SIZE_RELATIVE_MASK) != 0;
+ }
+
/**
* Tells whether the given property value is relative to the width of the
* containing block.
@@ -190,6 +205,13 @@ public boolean isBlockHeightRelative(int i) {
return (masks[i] & BLOCK_HEIGHT_RELATIVE_MASK) != 0;
}
+ /**
+ * Tells whether the given property value is relative to the viewport.
+ */
+ public boolean isViewportRelative(int i) {
+ return (masks[i] & VIEWPORT_RELATIVE_MASK) != 0;
+ }
+
/**
* Puts a property value, given the property index.
*
@@ -206,7 +228,7 @@ public void putValue(int i, Value v) {
* @param i The property index.
* @param m The property mask.
*/
- public void putMask(int i, short m) {
+ public void putMask(int i, int m) {
masks[i] = m;
}
@@ -223,9 +245,9 @@ public void putImportant(int i, boolean b) {
/**
* Sets the origin of the given value.
*/
- public void putOrigin(int i, short val) {
+ public void putOrigin(int i, int val) {
masks[i] &= ~ORIGIN_MASK;
- masks[i] |= (short) (val & ORIGIN_MASK);
+ masks[i] |= (val & ORIGIN_MASK);
}
/**
@@ -299,6 +321,26 @@ public void putFontSizeRelative(int i, boolean b) {
masks[i] &= ~FONT_SIZE_RELATIVE_MASK;
}
+ /**
+ * Sets the root-line-height-relative flag of a property value.
+ */
+ public void putRootLineHeightRelative(int i, boolean b) {
+ if (b)
+ masks[i] |= ROOT_LINE_HEIGHT_RELATIVE_MASK;
+ else
+ masks[i] &= ~ROOT_LINE_HEIGHT_RELATIVE_MASK;
+ }
+
+ /**
+ * Sets the root-font-size-relative flag of a property value.
+ */
+ public void putRootFontSizeRelative(int i, boolean b) {
+ if (b)
+ masks[i] |= ROOT_FONT_SIZE_RELATIVE_MASK;
+ else
+ masks[i] &= ~ROOT_FONT_SIZE_RELATIVE_MASK;
+ }
+
/**
* Sets the block-width-relative flag of a property value.
*/
@@ -319,6 +361,16 @@ public void putBlockHeightRelative(int i, boolean b) {
masks[i] &= ~BLOCK_HEIGHT_RELATIVE_MASK;
}
+ /**
+ * Sets the viewport-relative flag of a property value.
+ */
+ public void putViewportRelative(int i, boolean b) {
+ if (b)
+ masks[i] |= VIEWPORT_RELATIVE_MASK;
+ else
+ masks[i] &= ~VIEWPORT_RELATIVE_MASK;
+ }
+
/**
* Returns a printable representation of this style map.
*/
diff --git a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/AbstractValueManager.java b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/AbstractValueManager.java
index 4b6ada07d..2a6c764f8 100644
--- a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/AbstractValueManager.java
+++ b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/AbstractValueManager.java
@@ -18,9 +18,9 @@
*/
package io.sf.carte.echosvg.css.engine.value;
+import org.w3c.css.om.unit.CSSUnit;
import org.w3c.dom.DOMException;
-import org.w3c.css.om.unit.CSSUnit;
import io.sf.carte.echosvg.css.dom.CSSValue.Type;
import io.sf.carte.echosvg.css.engine.CSSEngine;
import io.sf.carte.echosvg.css.engine.CSSStylableElement;
diff --git a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/ColorFunction.java b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/ColorFunction.java
index 11196f411..d4012a2b2 100644
--- a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/ColorFunction.java
+++ b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/ColorFunction.java
@@ -25,9 +25,8 @@
import org.w3c.api.DOMSyntaxException;
import org.w3c.css.om.typed.CSSColor;
import org.w3c.css.om.typed.CSSStyleValueList;
-import org.w3c.dom.DOMException;
-
import org.w3c.css.om.unit.CSSUnit;
+import org.w3c.dom.DOMException;
/**
* color() function.
diff --git a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/LCHColorValue.java b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/LCHColorValue.java
index 52d79fa6b..46d273651 100644
--- a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/LCHColorValue.java
+++ b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/LCHColorValue.java
@@ -21,9 +21,9 @@
import org.w3c.api.DOMSyntaxException;
import org.w3c.css.om.typed.CSSLCH;
import org.w3c.css.om.typed.CSSNumericValue;
+import org.w3c.css.om.unit.CSSUnit;
import org.w3c.dom.DOMException;
-import org.w3c.css.om.unit.CSSUnit;
import io.sf.carte.echosvg.css.engine.value.svg.SVGValueConstants;
/**
diff --git a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/LabColorValue.java b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/LabColorValue.java
index edf8eb465..17cb92ed2 100644
--- a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/LabColorValue.java
+++ b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/LabColorValue.java
@@ -21,9 +21,9 @@
import org.w3c.api.DOMSyntaxException;
import org.w3c.css.om.typed.CSSLab;
import org.w3c.css.om.typed.CSSNumericValue;
+import org.w3c.css.om.unit.CSSUnit;
import org.w3c.dom.DOMException;
-import org.w3c.css.om.unit.CSSUnit;
import io.sf.carte.echosvg.css.engine.value.svg.SVGValueConstants;
/**
diff --git a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/LengthManager.java b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/LengthManager.java
index b2e799e4b..48c5072d8 100644
--- a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/LengthManager.java
+++ b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/LengthManager.java
@@ -18,11 +18,12 @@
*/
package io.sf.carte.echosvg.css.engine.value;
+import org.w3c.css.om.unit.CSSUnit;
import org.w3c.dom.DOMException;
-import org.w3c.css.om.unit.CSSUnit;
import io.sf.carte.doc.style.css.nsac.LexicalUnit;
import io.sf.carte.doc.style.css.property.NumberValue;
+import io.sf.carte.echosvg.css.Viewport;
import io.sf.carte.echosvg.css.dom.CSSValue.Type;
import io.sf.carte.echosvg.css.engine.CSSContext;
import io.sf.carte.echosvg.css.engine.CSSEngine;
@@ -53,11 +54,7 @@ public abstract class LengthManager extends AbstractValueManager {
public Value createValue(LexicalUnit lu, CSSEngine engine) throws DOMException {
switch (lu.getLexicalUnitType()) {
case DIMENSION:
- Value value = createLength(lu);
- if (value != null) {
- return value;
- }
- break;
+ return createLength(lu);
case INTEGER:
return new FloatValue(CSSUnit.CSS_NUMBER, lu.getIntegerValue());
@@ -73,11 +70,11 @@ public Value createValue(LexicalUnit lu, CSSEngine engine) throws DOMException {
throw createInvalidLexicalUnitDOMException(lu.getLexicalUnitType());
}
- static FloatValue createLength(LexicalUnit lu) {
+ FloatValue createLength(LexicalUnit lu) throws DOMException {
if (CSSUnit.isLengthUnitType(lu.getCssUnit())) {
return new FloatValue(lu.getCssUnit(), lu.getFloatValue());
}
- return null;
+ throw createInvalidLexicalUnitDOMException(lu.getLexicalUnitType());
}
/**
@@ -169,13 +166,89 @@ public Value computeValue(CSSStylableElement elt, String pseudo, CSSEngine engin
fs = (float) (value.getFloatValue() * (Math.sqrt(w * w + h * h) / SQRT2) / 100.0);
}
return new FloatValue(CSSUnit.CSS_NUMBER, fs);
+
+ case CSSUnit.CSS_LH:
+ sm.putLineHeightRelative(idx, true);
+
+ v = value.getFloatValue();
+ int lhidx = engine.getLineHeightIndex();
+ cv = engine.getComputedStyle(elt, pseudo, lhidx);
+ fs = lengthValue(cv);
+ return new FloatValue(CSSUnit.CSS_NUMBER, v * fs);
+
+ case CSSUnit.CSS_REM:
+ sm.putRootFontSizeRelative(idx, true);
+
+ v = value.getFloatValue();
+ fsidx = engine.getFontSizeIndex();
+ CSSStylableElement root = (CSSStylableElement) elt.getOwnerDocument().getDocumentElement();
+ cv = engine.getComputedStyle(root, null, fsidx);
+ fs = lengthValue(cv);
+ return new FloatValue(CSSUnit.CSS_NUMBER, v * fs);
+
+ case CSSUnit.CSS_REX:
+ sm.putRootFontSizeRelative(idx, true);
+
+ v = value.getFloatValue();
+ fsidx = engine.getFontSizeIndex();
+ root = (CSSStylableElement) elt.getOwnerDocument().getDocumentElement();
+ cv = engine.getComputedStyle(root, null, fsidx);
+ fs = lengthValue(cv);
+ return new FloatValue(CSSUnit.CSS_NUMBER, v * fs * 0.5f);
+
+ case CSSUnit.CSS_RLH:
+ sm.putRootLineHeightRelative(idx, true);
+
+ v = value.getFloatValue();
+ lhidx = engine.getLineHeightIndex();
+ root = (CSSStylableElement) elt.getOwnerDocument().getDocumentElement();
+ cv = engine.getComputedStyle(root, null, lhidx);
+ fs = lengthValue(cv);
+ return new FloatValue(CSSUnit.CSS_NUMBER, v * fs);
+
+ case CSSUnit.CSS_VW:
+ sm.putViewportRelative(idx, true);
+
+ v = lengthValue(value);
+ return new FloatValue(CSSUnit.CSS_NUMBER, v *
+ engine.getCSSContext().getViewport(elt).getWidth() * 0.01f);
+
+ case CSSUnit.CSS_VH:
+ sm.putViewportRelative(idx, true);
+
+ v = lengthValue(value);
+ return new FloatValue(CSSUnit.CSS_NUMBER, v *
+ engine.getCSSContext().getViewport(elt).getHeight() * 0.01f);
+
+ case CSSUnit.CSS_VMIN:
+ sm.putViewportRelative(idx, true);
+
+ v = lengthValue(value);
+ Viewport vp = engine.getCSSContext().getViewport(elt);
+ float w = vp.getWidth();
+ float h = vp.getHeight();
+ float min = Math.min(w, h);
+ return new FloatValue(CSSUnit.CSS_NUMBER, v * min * 0.01f);
+
+ case CSSUnit.CSS_VMAX:
+ sm.putViewportRelative(idx, true);
+
+ v = lengthValue(value);
+ vp = engine.getCSSContext().getViewport(elt);
+ w = vp.getWidth();
+ h = vp.getHeight();
+ float max = Math.max(w, h);
+ return new FloatValue(CSSUnit.CSS_NUMBER, v * max * 0.01f);
+
case CSSUnit.CSS_INVALID:
+ case CSSUnit.CSS_OTHER:
break;
default:
// Maybe it is one of the new absolute length units
try {
value = new FloatValue(CSSUnit.CSS_NUMBER,
- NumberValue.floatValueConversion(value.getFloatValue(), value.getCSSUnit(), CSSUnit.CSS_PX));
+ NumberValue.floatValueConversion(value.getFloatValue(), value.getCSSUnit(), CSSUnit.CSS_MM)
+ / engine.getCSSContext().getPixelUnitToMillimeter());
} catch (DOMException e) {
}
}
diff --git a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/RectManager.java b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/RectManager.java
index e816010c4..8a5d79264 100644
--- a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/RectManager.java
+++ b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/RectManager.java
@@ -91,11 +91,7 @@ private Value createRectComponent(LexicalUnit lu) throws DOMException {
}
break;
case DIMENSION:
- NumericValue value = createLength(lu);
- if (value != null) {
- return value;
- }
- break;
+ return createLength(lu);
case INTEGER:
return new FloatValue(CSSUnit.CSS_NUMBER, lu.getIntegerValue());
case REAL:
diff --git a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/RectValue.java b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/RectValue.java
index 9505cba4a..f6dd3d454 100644
--- a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/RectValue.java
+++ b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/RectValue.java
@@ -20,9 +20,8 @@
import org.w3c.api.DOMSyntaxException;
import org.w3c.css.om.typed.CSSRectValue;
-import org.w3c.dom.DOMException;
-
import org.w3c.css.om.unit.CSSUnit;
+import org.w3c.dom.DOMException;
/**
* This class represents CSS rect values.
diff --git a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/ValueConstants.java b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/ValueConstants.java
index 01051c058..6a03e46bc 100644
--- a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/ValueConstants.java
+++ b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/ValueConstants.java
@@ -19,6 +19,7 @@
package io.sf.carte.echosvg.css.engine.value;
import org.w3c.css.om.unit.CSSUnit;
+
import io.sf.carte.echosvg.util.CSSConstants;
/**
diff --git a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/css2/FontSizeManager.java b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/css2/FontSizeManager.java
index 245d7dfae..abb6c7c2e 100644
--- a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/css2/FontSizeManager.java
+++ b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/css2/FontSizeManager.java
@@ -24,6 +24,7 @@
import org.w3c.dom.DOMException;
import io.sf.carte.doc.style.css.nsac.LexicalUnit;
+import io.sf.carte.doc.style.css.property.NumberValue;
import io.sf.carte.echosvg.css.Viewport;
import io.sf.carte.echosvg.css.dom.CSSValue.Type;
import io.sf.carte.echosvg.css.engine.CSSContext;
@@ -167,77 +168,117 @@ public Value computeValue(CSSStylableElement elt, String pseudo, CSSEngine engin
float scale = 1.0f;
boolean doParentRelative = false;
- switch (value.getCSSUnit()) {
- case CSSUnit.CSS_NUMBER:
- case CSSUnit.CSS_PX:
- return value;
+ if (value.getPrimitiveType() == Type.NUMERIC) {
+ switch (value.getCSSUnit()) {
+ case CSSUnit.CSS_NUMBER:
+ case CSSUnit.CSS_PX:
+ return value;
- case CSSUnit.CSS_MM:
- CSSContext ctx = engine.getCSSContext();
- float v = lengthValue(value);
- return new FloatValue(CSSUnit.CSS_NUMBER, v / ctx.getPixelUnitToMillimeter());
-
- case CSSUnit.CSS_CM:
- ctx = engine.getCSSContext();
- v = lengthValue(value);
- return new FloatValue(CSSUnit.CSS_NUMBER, v * 10f / ctx.getPixelUnitToMillimeter());
-
- case CSSUnit.CSS_IN:
- ctx = engine.getCSSContext();
- v = lengthValue(value);
- return new FloatValue(CSSUnit.CSS_NUMBER, v * 25.4f / ctx.getPixelUnitToMillimeter());
-
- case CSSUnit.CSS_PT:
- ctx = engine.getCSSContext();
- v = lengthValue(value);
- return new FloatValue(CSSUnit.CSS_NUMBER, v * 25.4f / (72f * ctx.getPixelUnitToMillimeter()));
-
- case CSSUnit.CSS_PC:
- ctx = engine.getCSSContext();
- v = lengthValue(value);
- return new FloatValue(CSSUnit.CSS_NUMBER, (v * 25.4f / (6f * ctx.getPixelUnitToMillimeter())));
-
- case CSSUnit.CSS_EM:
- doParentRelative = true;
- scale = lengthValue(value);
- break;
- case CSSUnit.CSS_EX:
- doParentRelative = true;
- scale = lengthValue(value) * 0.5f; // !!! x-height
- break;
- case CSSUnit.CSS_PERCENTAGE:
- doParentRelative = true;
- scale = value.getFloatValue() * 0.01f;
- break;
- case CSSUnit.CSS_REM:
- scale = lengthValue(value);
- return rootRelative(elt, engine, idx, scale);
- case CSSUnit.CSS_REX:
- scale = lengthValue(value) * 0.5f;
- return rootRelative(elt, engine, idx, scale);
- case CSSUnit.CSS_VW:
- v = lengthValue(value);
- return new FloatValue(CSSUnit.CSS_NUMBER, v *
- engine.getCSSContext().getViewport(elt).getWidth() * 0.01f);
- case CSSUnit.CSS_VH:
- v = lengthValue(value);
- return new FloatValue(CSSUnit.CSS_NUMBER, v *
- engine.getCSSContext().getViewport(elt).getHeight() * 0.01f);
- case CSSUnit.CSS_VMIN:
- v = lengthValue(value);
- Viewport vp = engine.getCSSContext().getViewport(elt);
- float w = vp.getWidth();
- float h = vp.getHeight();
- float min = Math.min(w, h);
- return new FloatValue(CSSUnit.CSS_NUMBER, v * min * 0.01f);
- case CSSUnit.CSS_VMAX:
- v = lengthValue(value);
- vp = engine.getCSSContext().getViewport(elt);
- w = vp.getWidth();
- h = vp.getHeight();
- float max = Math.max(w, h);
- return new FloatValue(CSSUnit.CSS_NUMBER, v * max * 0.01f);
- default:
+ case CSSUnit.CSS_MM:
+ CSSContext ctx = engine.getCSSContext();
+ float v = lengthValue(value);
+ return new FloatValue(CSSUnit.CSS_NUMBER, v / ctx.getPixelUnitToMillimeter());
+
+ case CSSUnit.CSS_CM:
+ ctx = engine.getCSSContext();
+ v = lengthValue(value);
+ return new FloatValue(CSSUnit.CSS_NUMBER, v * 10f / ctx.getPixelUnitToMillimeter());
+
+ case CSSUnit.CSS_IN:
+ ctx = engine.getCSSContext();
+ v = lengthValue(value);
+ return new FloatValue(CSSUnit.CSS_NUMBER, v * 25.4f / ctx.getPixelUnitToMillimeter());
+
+ case CSSUnit.CSS_PT:
+ ctx = engine.getCSSContext();
+ v = lengthValue(value);
+ return new FloatValue(CSSUnit.CSS_NUMBER, v * 25.4f / (72f * ctx.getPixelUnitToMillimeter()));
+
+ case CSSUnit.CSS_PC:
+ ctx = engine.getCSSContext();
+ v = lengthValue(value);
+ return new FloatValue(CSSUnit.CSS_NUMBER, (v * 25.4f / (6f * ctx.getPixelUnitToMillimeter())));
+
+ case CSSUnit.CSS_EM:
+ doParentRelative = true;
+ scale = lengthValue(value);
+ break;
+ case CSSUnit.CSS_EX:
+ doParentRelative = true;
+ scale = lengthValue(value) * 0.5f; // !!! x-height
+ break;
+ case CSSUnit.CSS_PERCENTAGE:
+ doParentRelative = true;
+ scale = value.getFloatValue() * 0.01f;
+ break;
+ case CSSUnit.CSS_LH:
+ sm.putLineHeightRelative(idx, true);
+ scale = lengthValue(value);
+ int lhidx = engine.getLineHeightIndex();
+ CSSStylableElement p = CSSEngine.getParentCSSStylableElement(elt);
+ float lh;
+ if (p == null) {
+ lh = 1.2f * engine.getCSSContext().getMediumFontSize();
+ } else {
+ Value cs = engine.getComputedStyle(p, null, lhidx);
+ lh = lengthValue(cs);
+ }
+ return new FloatValue(CSSUnit.CSS_NUMBER, lh * scale);
+ case CSSUnit.CSS_REM:
+ sm.putRootFontSizeRelative(idx, true);
+ scale = lengthValue(value);
+ return rootRelative(elt, engine, idx, scale);
+ case CSSUnit.CSS_REX:
+ sm.putRootFontSizeRelative(idx, true);
+ scale = lengthValue(value) * 0.5f;
+ return rootRelative(elt, engine, idx, scale);
+ case CSSUnit.CSS_RLH:
+ sm.putLineHeightRelative(idx, true);
+ scale = lengthValue(value);
+ lhidx = engine.getLineHeightIndex();
+ CSSStylableElement root = (CSSStylableElement) elt.getOwnerDocument().getDocumentElement();
+ if (elt == root) {
+ lh = 1.2f * engine.getCSSContext().getMediumFontSize();
+ } else {
+ Value cs = engine.getComputedStyle(root, null, lhidx);
+ lh = lengthValue(cs);
+ }
+ return new FloatValue(CSSUnit.CSS_NUMBER, lh * scale);
+ case CSSUnit.CSS_VW:
+ sm.putViewportRelative(idx, true);
+ v = lengthValue(value);
+ return new FloatValue(CSSUnit.CSS_NUMBER,
+ v * engine.getCSSContext().getViewport(elt).getWidth() * 0.01f);
+ case CSSUnit.CSS_VH:
+ sm.putViewportRelative(idx, true);
+ v = lengthValue(value);
+ return new FloatValue(CSSUnit.CSS_NUMBER,
+ v * engine.getCSSContext().getViewport(elt).getHeight() * 0.01f);
+ case CSSUnit.CSS_VMIN:
+ sm.putViewportRelative(idx, true);
+ v = lengthValue(value);
+ Viewport vp = engine.getCSSContext().getViewport(elt);
+ float w = vp.getWidth();
+ float h = vp.getHeight();
+ float min = Math.min(w, h);
+ return new FloatValue(CSSUnit.CSS_NUMBER, v * min * 0.01f);
+ case CSSUnit.CSS_VMAX:
+ sm.putViewportRelative(idx, true);
+ v = lengthValue(value);
+ vp = engine.getCSSContext().getViewport(elt);
+ w = vp.getWidth();
+ h = vp.getHeight();
+ float max = Math.max(w, h);
+ return new FloatValue(CSSUnit.CSS_NUMBER, v * max * 0.01f);
+ default:
+ // Maybe it is one of the new absolute length units
+ try {
+ return new FloatValue(CSSUnit.CSS_NUMBER,
+ NumberValue.floatValueConversion(value.getFloatValue(), value.getCSSUnit(),
+ CSSUnit.CSS_MM) / engine.getCSSContext().getPixelUnitToMillimeter());
+ } catch (DOMException e) {
+ }
+ }
}
if (value.isIdentifier(CSSConstants.CSS_LARGER_VALUE)) {
@@ -251,8 +292,7 @@ public Value computeValue(CSSStylableElement elt, String pseudo, CSSEngine engin
if (doParentRelative) {
sm.putParentRelative(idx, true);
- CSSStylableElement p;
- p = CSSEngine.getParentCSSStylableElement(elt);
+ CSSStylableElement p = CSSEngine.getParentCSSStylableElement(elt);
float fs;
if (p == null) {
CSSContext ctx = engine.getCSSContext();
diff --git a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/svg/GlyphOrientationManager.java b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/svg/GlyphOrientationManager.java
index efaa647a9..817a69488 100644
--- a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/svg/GlyphOrientationManager.java
+++ b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/svg/GlyphOrientationManager.java
@@ -22,6 +22,7 @@
import org.w3c.dom.DOMException;
import io.sf.carte.doc.style.css.nsac.LexicalUnit;
+import io.sf.carte.doc.style.css.property.NumberValue;
import io.sf.carte.echosvg.css.engine.CSSEngine;
import io.sf.carte.echosvg.css.engine.value.AbstractValueManager;
import io.sf.carte.echosvg.css.engine.value.FloatValue;
@@ -121,8 +122,10 @@ public Value createFloatValue(short type, float floatValue) throws DOMException
case CSSUnit.CSS_GRAD:
case CSSUnit.CSS_RAD:
return new FloatValue(type, floatValue);
+ default:
+ float f = NumberValue.floatValueConversion(floatValue, type, CSSUnit.CSS_DEG);
+ return new FloatValue(CSSUnit.CSS_DEG, f);
}
- throw createInvalidFloatValueDOMException(floatValue);
}
}
diff --git a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/svg12/LineHeightManager.java b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/svg12/LineHeightManager.java
index 0b17a6ca8..1e1061361 100644
--- a/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/svg12/LineHeightManager.java
+++ b/echosvg-css/src/main/java/io/sf/carte/echosvg/css/engine/value/svg12/LineHeightManager.java
@@ -148,6 +148,29 @@ public Value computeValue(CSSStylableElement elt, String pseudo, CSSEngine engin
return new FloatValue(CSSUnit.CSS_NUMBER, v * fs * 0.01f);
}
+ case CSSUnit.CSS_LH:
+ float lh;
+ float v = value.getFloatValue();
+ CSSStylableElement p = CSSEngine.getParentCSSStylableElement(elt);
+ if (p != null) {
+ int lhidx = engine.getLineHeightIndex();
+ lh = engine.getComputedStyle(p, null, lhidx).getFloatValue();
+ } else {
+ lh = 1.2f * engine.getCSSContext().getMediumFontSize();
+ }
+ return new FloatValue(CSSUnit.CSS_NUMBER, v * lh);
+
+ case CSSUnit.CSS_RLH:
+ v = value.getFloatValue();
+ CSSStylableElement root = (CSSStylableElement) elt.getOwnerDocument().getDocumentElement();
+ if (root != elt) {
+ int lhidx = engine.getLineHeightIndex();
+ lh = engine.getComputedStyle(root, null, lhidx).getFloatValue();
+ } else {
+ lh = 1.2f * engine.getCSSContext().getMediumFontSize();
+ }
+ return new FloatValue(CSSUnit.CSS_NUMBER, v * lh);
+
default:
return super.computeValue(elt, pseudo, engine, idx, sm, value);
}
diff --git a/echosvg-test/src/test/java/io/sf/carte/echosvg/test/svg/AbstractSamplesRendering.java b/echosvg-test/src/test/java/io/sf/carte/echosvg/test/svg/AbstractSamplesRendering.java
index b11df6617..9ce96b131 100644
--- a/echosvg-test/src/test/java/io/sf/carte/echosvg/test/svg/AbstractSamplesRendering.java
+++ b/echosvg-test/src/test/java/io/sf/carte/echosvg/test/svg/AbstractSamplesRendering.java
@@ -38,6 +38,8 @@ public class AbstractSamplesRendering {
static final String BROWSER_MEDIA = "screen";
+ static final String PRINT_MEDIA = "print";
+
/**
* To test the tEXt chunk.
*/
@@ -326,7 +328,7 @@ void testXHTMLErrIgnore(String file, String media, int expectedErrorCount)
* @throws IOException if an I/O error occurs.
*/
void testHTML(String file) throws TranscoderException, IOException {
- testHTML(file, null);
+ testHTML(file, null, null);
}
/**
@@ -337,13 +339,15 @@ void testHTML(String file) throws TranscoderException, IOException {
* reference image.
*
*
- * @param file the HTML file to test.
- * @param the selector that locates the desired SVG element.
+ * @param file the HTML file to test.
+ * @param the selector that locates the desired SVG element.
+ * @param media the media to test, or {@code null} if default media.
* @throws TranscoderException
* @throws IOException if an I/O error occurs.
*/
- void testHTML(String file, String selector) throws TranscoderException, IOException {
+ void testHTML(String file, String selector, String media) throws TranscoderException, IOException {
RenderingTest runner = new HTMLRenderingAccuracyTest(selector);
+ runner.setMedia(media);
runner.setFile(file);
runner.runTest(getBelowThresholdAllowed(), getOverThresholdAllowed());
}
diff --git a/echosvg-test/src/test/java/io/sf/carte/echosvg/test/svg/SamplesSpecRenderingTest.java b/echosvg-test/src/test/java/io/sf/carte/echosvg/test/svg/SamplesSpecRenderingTest.java
index 547b52b69..6e481f6fb 100644
--- a/echosvg-test/src/test/java/io/sf/carte/echosvg/test/svg/SamplesSpecRenderingTest.java
+++ b/echosvg-test/src/test/java/io/sf/carte/echosvg/test/svg/SamplesSpecRenderingTest.java
@@ -763,17 +763,22 @@ public void testUserSheet() throws TranscoderException, IOException {
@Test
public void testHTMLEmbed() throws TranscoderException, IOException {
- testHTML("samples/tests/spec/styling/css2.html");
+ testHTML("samples/tests/spec/styling/css3.html");
+ }
+
+ @Test
+ public void testHTMLEmbedPrint() throws TranscoderException, IOException {
+ testHTML("samples/tests/spec/styling/css3.html", null, PRINT_MEDIA);
}
@Test
public void testHTMLEmbedSelector() throws TranscoderException, IOException {
- testHTML("samples/tests/spec/styling/css2.html", "#theSVG");
+ testHTML("samples/tests/spec/styling/css3.html", "#theSVG", null);
}
@Test
public void testXHTMLEmbed() throws TranscoderException, IOException {
- testXHTML("samples/tests/spec/styling/css2.xhtml");
+ testXHTML("samples/tests/spec/styling/css3.xhtml");
}
@Test
diff --git a/samples/tests/spec/styling/css2.html b/samples/tests/spec/styling/css3.html
similarity index 96%
rename from samples/tests/spec/styling/css2.html
rename to samples/tests/spec/styling/css3.html
index f7685cfeb..5a0b8b7ee 100644
--- a/samples/tests/spec/styling/css2.html
+++ b/samples/tests/spec/styling/css3.html
@@ -38,7 +38,7 @@