diff --git a/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/AbstractSVGAnimatedLength.java b/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/AbstractSVGAnimatedLength.java index 8c9b55e22..ae5e75234 100644 --- a/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/AbstractSVGAnimatedLength.java +++ b/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/AbstractSVGAnimatedLength.java @@ -18,6 +18,7 @@ */ package io.sf.carte.echosvg.anim.dom; +import org.w3c.css.om.unit.CSSUnit; import org.w3c.dom.Attr; import org.w3c.dom.DOMException; import org.w3c.dom.svg.SVGAnimatedLength; @@ -109,7 +110,7 @@ public float getDefault() { AnimSVGLength length = new AnimSVGLength(direction); length.parse(getDefaultValue()); try { - return UnitProcessor.svgToUserSpace(length.value, length.unitType, direction, + return UnitProcessor.cssToUserSpace(length.value, length.unitType, direction, length.context); } catch (IllegalArgumentException ex) { // Only if the default is broken @@ -161,7 +162,7 @@ public float getCheckedValue() { if (baseVal.missing) { throw new LiveAttributeException(element, localName, LiveAttributeException.ERR_ATTRIBUTE_MISSING, null); - } else if (baseVal.unitType == SVGLength.SVG_LENGTHTYPE_UNKNOWN) { + } else if (baseVal.unitType == CSSUnit.CSS_INVALID) { throw new LiveAttributeException(element, localName, LiveAttributeException.ERR_ATTRIBUTE_MALFORMED, baseVal.getValueAsString()); } @@ -197,7 +198,7 @@ protected void updateAnimatedValue(AnimatableValue val) { @Override public AnimatableValue getUnderlyingValue(AnimationTarget target) { SVGLength base = getBaseVal(); - return new AnimatableLengthValue(target, base.getUnitType(), base.getValueInSpecifiedUnits(), + return new AnimatableLengthValue(target, base.getCSSUnitType(), base.getValueInSpecifiedUnits(), target.getPercentageInterpretation(getNamespaceURI(), getLocalName(), false)); } @@ -339,9 +340,14 @@ public AnimSVGLength(short direction) { super(direction); } - /** - * DOM: Implements {@link SVGLength#getUnitType()}. - */ + @Override + public short getCSSUnitType() { + if (hasAnimVal) { + return super.getCSSUnitType(); + } + return getBaseVal().getCSSUnitType(); + } + @Override public short getUnitType() { if (hasAnimVal) { @@ -350,9 +356,6 @@ public short getUnitType() { return getBaseVal().getUnitType(); } - /** - * DOM: Implements {@link SVGLength#getValue()}. - */ @Override public float getValue() { if (hasAnimVal) { @@ -361,9 +364,6 @@ public float getValue() { return getBaseVal().getValue(); } - /** - * DOM: Implements {@link SVGLength#getValueInSpecifiedUnits()}. - */ @Override public float getValueInSpecifiedUnits() { if (hasAnimVal) { @@ -372,9 +372,6 @@ public float getValueInSpecifiedUnits() { return getBaseVal().getValueInSpecifiedUnits(); } - /** - * DOM: Implements {@link SVGLength#getValueAsString()}. - */ @Override public String getValueAsString() { if (hasAnimVal) { @@ -383,41 +380,31 @@ public String getValueAsString() { return getBaseVal().getValueAsString(); } - /** - * DOM: Implements {@link SVGLength#setValue(float)}. - */ @Override public void setValue(float value) throws DOMException { throw element.createDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, "readonly.length", null); } - /** - * DOM: Implements {@link SVGLength#setValueInSpecifiedUnits(float)}. - */ @Override public void setValueInSpecifiedUnits(float value) throws DOMException { throw element.createDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, "readonly.length", null); } - /** - * DOM: Implements {@link SVGLength#setValueAsString(String)}. - */ @Override public void setValueAsString(String value) throws DOMException { throw element.createDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, "readonly.length", null); } - /** - * DOM: Implements {@link SVGLength#newValueSpecifiedUnits(short,float)}. - */ + @Override + public void newValueSpecifiedCSSUnits(short unit, float value) { + throw element.createDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, "readonly.length", null); + } + @Override public void newValueSpecifiedUnits(short unit, float value) { throw element.createDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, "readonly.length", null); } - /** - * DOM: Implements {@link SVGLength#convertToSpecifiedUnits(short)}. - */ @Override public void convertToSpecifiedUnits(short unit) { throw element.createDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, "readonly.length", null); @@ -434,11 +421,11 @@ protected SVGOMElement getAssociatedElement() { /** * Sets the animated value. * - * @param type one of the values defines in org.w3c.dom.svg.SVGLength - * @param val the length + * @param type one of the values defines in {@link org.w3c.css.om.unit.CSSUnit CSSUnit}. + * @param val the length. */ protected void setAnimatedValue(int type, float val) { - super.newValueSpecifiedUnits((short) type, val); + super.newValueSpecifiedCSSUnits((short) type, val); } } diff --git a/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/AbstractSVGLength.java b/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/AbstractSVGLength.java index cf0f16c33..f85e0c37d 100644 --- a/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/AbstractSVGLength.java +++ b/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/AbstractSVGLength.java @@ -18,10 +18,12 @@ */ package io.sf.carte.echosvg.anim.dom; +import org.w3c.css.om.unit.CSSUnit; import org.w3c.dom.DOMException; import org.w3c.dom.Element; import org.w3c.dom.svg.SVGLength; +import io.sf.carte.doc.style.css.property.NumberValue; import io.sf.carte.echosvg.parser.LengthParser; import io.sf.carte.echosvg.parser.ParseException; import io.sf.carte.echosvg.parser.UnitProcessor; @@ -60,7 +62,7 @@ public abstract class AbstractSVGLength implements SVGLength { public static final short OTHER_LENGTH = UnitProcessor.OTHER_LENGTH; /** - * The type of this length. + * The unit of this length, as one of the constants in {@link CSSUnit}. */ protected short unitType; @@ -79,11 +81,6 @@ public abstract class AbstractSVGLength implements SVGLength { */ protected UnitProcessor.Context context; - /** - * The unit string representations. - */ - protected static final String[] UNITS = { "", "", "%", "em", "ex", "px", "cm", "mm", "in", "pt", "pc" }; - /** * Return the SVGElement associated to this length. */ @@ -96,18 +93,60 @@ public AbstractSVGLength(short direction) { context = new DefaultContext(); this.direction = direction; this.value = 0.0f; - this.unitType = SVGLength.SVG_LENGTHTYPE_NUMBER; + this.unitType = CSSUnit.CSS_NUMBER; } - /** - * DOM: Implements {@link SVGLength#getUnitType()}. - */ @Override - public short getUnitType() { + public short getCSSUnitType() { revalidate(); return unitType; } + @Override + public short getUnitType() { + return getSVGUnitType(getCSSUnitType()); + } + + private static short getSVGUnitType(short cssUnit) { + short svgUnit; + switch (cssUnit) { + case CSSUnit.CSS_NUMBER: + svgUnit = SVGLength.SVG_LENGTHTYPE_NUMBER; + break; + case CSSUnit.CSS_PX: + svgUnit = SVGLength.SVG_LENGTHTYPE_PX; + break; + case CSSUnit.CSS_EM: + svgUnit = SVGLength.SVG_LENGTHTYPE_EMS; + break; + case CSSUnit.CSS_EX: + svgUnit = SVGLength.SVG_LENGTHTYPE_EXS; + break; + case CSSUnit.CSS_IN: + svgUnit = SVGLength.SVG_LENGTHTYPE_IN; + break; + case CSSUnit.CSS_CM: + svgUnit = SVGLength.SVG_LENGTHTYPE_CM; + break; + case CSSUnit.CSS_MM: + svgUnit = SVGLength.SVG_LENGTHTYPE_MM; + break; + case CSSUnit.CSS_PC: + svgUnit = SVGLength.SVG_LENGTHTYPE_PC; + break; + case CSSUnit.CSS_PT: + svgUnit = SVGLength.SVG_LENGTHTYPE_PT; + break; + case CSSUnit.CSS_PERCENTAGE: + svgUnit = SVGLength.SVG_LENGTHTYPE_PERCENTAGE; + break; + default: + svgUnit = SVGLength.SVG_LENGTHTYPE_UNKNOWN; + break; + } + return svgUnit; + } + /** * DOM: Implements {@link SVGLength#getValue()}. */ @@ -115,7 +154,7 @@ public short getUnitType() { public float getValue() { revalidate(); try { - return UnitProcessor.svgToUserSpace(value, unitType, direction, context); + return UnitProcessor.cssToUserSpace(value, unitType, direction, context); } catch (IllegalArgumentException ex) { // XXX Should we throw an exception here when the length // type is unknown? @@ -128,7 +167,7 @@ public float getValue() { */ @Override public void setValue(float value) throws DOMException { - this.value = UnitProcessor.userSpaceToSVG(value, unitType, direction, context); + this.value = UnitProcessor.userSpaceToCSS(value, unitType, direction, context); reset(); } @@ -157,10 +196,10 @@ public void setValueInSpecifiedUnits(float value) throws DOMException { @Override public String getValueAsString() { revalidate(); - if (unitType == SVGLength.SVG_LENGTHTYPE_UNKNOWN) { + if (unitType == CSSUnit.CSS_INVALID) { return ""; } - return Float.toString(value) + UNITS[unitType]; + return Float.toString(value) + CSSUnit.dimensionUnitString(unitType); } /** @@ -176,18 +215,60 @@ public void setValueAsString(String value) throws DOMException { * DOM: Implements {@link SVGLength#newValueSpecifiedUnits(short,float)}. */ @Override - public void newValueSpecifiedUnits(short unit, float value) { + public void newValueSpecifiedCSSUnits(short unit, float value) { unitType = unit; this.value = value; reset(); } - /** - * DOM: Implements {@link SVGLength#convertToSpecifiedUnits(short)}. - */ @Override - public void convertToSpecifiedUnits(short unit) { + public void newValueSpecifiedUnits(short unitType, float valueInSpecifiedUnits) throws DOMException { + newValueSpecifiedCSSUnits(getCSSUnitType(unitType), valueInSpecifiedUnits); + } + + private static short getCSSUnitType(short svgUnit) throws DOMException { + short cssUnit; + switch (svgUnit) { + case SVGLength.SVG_LENGTHTYPE_NUMBER: + cssUnit = CSSUnit.CSS_NUMBER; + break; + case SVGLength.SVG_LENGTHTYPE_PX: + cssUnit = CSSUnit.CSS_PX; + break; + case SVGLength.SVG_LENGTHTYPE_EMS: + cssUnit = CSSUnit.CSS_EM; + break; + case SVGLength.SVG_LENGTHTYPE_EXS: + cssUnit = CSSUnit.CSS_EX; + break; + case SVGLength.SVG_LENGTHTYPE_IN: + cssUnit = CSSUnit.CSS_IN; + break; + case SVGLength.SVG_LENGTHTYPE_CM: + cssUnit = CSSUnit.CSS_CM; + break; + case SVGLength.SVG_LENGTHTYPE_MM: + cssUnit = CSSUnit.CSS_MM; + break; + case SVGLength.SVG_LENGTHTYPE_PC: + cssUnit = CSSUnit.CSS_PC; + break; + case SVGLength.SVG_LENGTHTYPE_PT: + cssUnit = CSSUnit.CSS_PT; + break; + case SVGLength.SVG_LENGTHTYPE_PERCENTAGE: + cssUnit = CSSUnit.CSS_PERCENTAGE; + break; + default: + throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Unit not supported: " + svgUnit); + } + return cssUnit; + } + + @Override + public void convertToSpecifiedUnits(short unit) throws DOMException { float v = getValue(); + v = NumberValue.floatValueConversion(v, unitType, getCSSUnitType(unit)); unitType = unit; setValue(v); } @@ -224,7 +305,7 @@ protected void parse(String s) { unitType = ur.unit; value = ur.value; } catch (ParseException e) { - unitType = SVG_LENGTHTYPE_UNKNOWN; + unitType = CSSUnit.CSS_INVALID; value = 0; } } @@ -263,6 +344,24 @@ public float getXHeight() { return 0.5f; } + @Override + public float getLineHeight() { + return getAssociatedElement().getSVGContext().getLineHeight(); + } + + /** + * Returns the :root font-size value. + */ + @Override + public float getRootFontSize() { + return getAssociatedElement().getSVGContext().getRootFontSize(); + } + + @Override + public float getRootLineHeight() { + return getAssociatedElement().getSVGContext().getRootLineHeight(); + } + /** * Returns the viewport width used to compute units. */ diff --git a/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/AbstractSVGLengthList.java b/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/AbstractSVGLengthList.java index f738cd014..c92ee6aab 100644 --- a/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/AbstractSVGLengthList.java +++ b/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/AbstractSVGLengthList.java @@ -18,6 +18,7 @@ */ package io.sf.carte.echosvg.anim.dom; +import org.w3c.css.om.unit.CSSUnit; import org.w3c.dom.DOMException; import org.w3c.dom.Element; import org.w3c.dom.svg.SVGException; @@ -27,6 +28,7 @@ import io.sf.carte.echosvg.dom.svg.AbstractSVGList; import io.sf.carte.echosvg.dom.svg.ListHandler; import io.sf.carte.echosvg.dom.svg.SVGItem; +import io.sf.carte.echosvg.parser.DefaultLengthHandler; import io.sf.carte.echosvg.parser.LengthListHandler; import io.sf.carte.echosvg.parser.LengthListParser; import io.sf.carte.echosvg.parser.ParseException; @@ -131,7 +133,7 @@ public SVGLength appendItem(SVGLength newItem) throws DOMException, SVGException @Override protected SVGItem createSVGItem(Object newItem) { SVGLength l = (SVGLength) newItem; - return new SVGLengthItem(l.getUnitType(), l.getValueInSpecifiedUnits(), direction); + return new SVGLengthItem(l.getCSSUnitType(), l.getValueInSpecifiedUnits(), direction); } /** @@ -229,7 +231,7 @@ protected void reset() { * Helper class to interface the {@link LengthListParser} and the * {@link ListHandler}. */ - protected class LengthListBuilder implements LengthListHandler { + protected class LengthListBuilder extends DefaultLengthHandler implements LengthListHandler { /** * The ListHandler to pass newly created {@link SVGLengthItem} objects to. @@ -266,7 +268,7 @@ public void startLengthList() throws ParseException { */ @Override public void startLength() throws ParseException { - currentType = SVGLength.SVG_LENGTHTYPE_NUMBER; + currentType = CSSUnit.CSS_NUMBER; currentValue = 0.0f; } @@ -278,76 +280,9 @@ public void lengthValue(float v) throws ParseException { currentValue = v; } - /** - * Implements {@link LengthListHandler#em()}. - */ - @Override - public void em() throws ParseException { - currentType = SVGLength.SVG_LENGTHTYPE_EMS; - } - - /** - * Implements {@link LengthListHandler#ex()}. - */ - @Override - public void ex() throws ParseException { - currentType = SVGLength.SVG_LENGTHTYPE_EXS; - } - - /** - * Implements {@link LengthListHandler#in()}. - */ - @Override - public void in() throws ParseException { - currentType = SVGLength.SVG_LENGTHTYPE_IN; - } - - /** - * Implements {@link LengthListHandler#cm()}. - */ - @Override - public void cm() throws ParseException { - currentType = SVGLength.SVG_LENGTHTYPE_CM; - } - - /** - * Implements {@link LengthListHandler#mm()}. - */ - @Override - public void mm() throws ParseException { - currentType = SVGLength.SVG_LENGTHTYPE_MM; - } - - /** - * Implements {@link LengthListHandler#pc()}. - */ - @Override - public void pc() throws ParseException { - currentType = SVGLength.SVG_LENGTHTYPE_PC; - } - - /** - * Implements {@link LengthListHandler#pt()}. - */ - @Override - public void pt() throws ParseException { - currentType = SVGLength.SVG_LENGTHTYPE_EMS; - } - - /** - * Implements {@link LengthListHandler#px()}. - */ - @Override - public void px() throws ParseException { - currentType = SVGLength.SVG_LENGTHTYPE_PX; - } - - /** - * Implements {@link LengthListHandler#percentage()}. - */ @Override - public void percentage() throws ParseException { - currentType = SVGLength.SVG_LENGTHTYPE_PERCENTAGE; + protected void setUnit(short unit) { + currentType = unit; } /** diff --git a/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/SVGOMAnimatedLengthList.java b/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/SVGOMAnimatedLengthList.java index 98d944aac..e63dbd639 100644 --- a/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/SVGOMAnimatedLengthList.java +++ b/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/SVGOMAnimatedLengthList.java @@ -149,7 +149,7 @@ public AnimatableValue getUnderlyingValue(AnimationTarget target) { float[] values = new float[n]; for (int i = 0; i < n; i++) { SVGLength l = ll.getItem(i); - types[i] = l.getUnitType(); + types[i] = l.getCSSUnitType(); values[i] = l.getValueInSpecifiedUnits(); } return new AnimatableLengthListValue(target, types, values, diff --git a/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/SVGOMElement.java b/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/SVGOMElement.java index 6b67258c2..8d8a0bfbb 100644 --- a/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/SVGOMElement.java +++ b/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/dom/SVGOMElement.java @@ -20,6 +20,7 @@ import java.util.LinkedList; +import org.w3c.css.om.unit.CSSUnit; import org.w3c.dom.Attr; import org.w3c.dom.DOMException; import org.w3c.dom.Element; @@ -29,7 +30,6 @@ import org.w3c.dom.svg.SVGElement; import org.w3c.dom.svg.SVGException; import org.w3c.dom.svg.SVGFitToViewBox; -import org.w3c.dom.svg.SVGLength; import org.w3c.dom.svg.SVGSVGElement; import io.sf.carte.echosvg.anim.values.AnimatableNumberOptionalNumberValue; @@ -746,8 +746,8 @@ public boolean useLinearRGBColorInterpolation() { * Converts the given SVG length into user units. * * @param v the SVG length value - * @param type the SVG length units (one of the - * {@link SVGLength}.SVG_LENGTH_* constants) + * @param type the CSS unit (one of the + * {@link CSSUnit}.CSS_* constants) * @param pcInterp how to interpretet percentage values (one of the * {@link SVGContext}.PERCENTAGE_* constants) * @return the SVG value in user units @@ -757,11 +757,11 @@ public float svgToUserSpace(float v, short type, short pcInterp) { if (unitContext == null) { unitContext = new UnitContext(); } - if (pcInterp == PERCENTAGE_FONT_SIZE && type == SVGLength.SVG_LENGTHTYPE_PERCENTAGE) { + if (pcInterp == PERCENTAGE_FONT_SIZE && type == CSSUnit.CSS_PERCENTAGE) { // XXX return 0f; } else { - return UnitProcessor.svgToUserSpace(v, type, (short) (3 - pcInterp), unitContext); + return UnitProcessor.cssToUserSpace(v, type, (short) (3 - pcInterp), unitContext); } } @@ -890,6 +890,21 @@ public float getFontSize() { return getSVGContext().getFontSize(); } + @Override + public float getLineHeight() { + return getSVGContext().getLineHeight(); + } + + @Override + public float getRootFontSize() { + return getSVGContext().getRootFontSize(); + } + + @Override + public float getRootLineHeight() { + return getSVGContext().getRootLineHeight(); + } + /** * Returns the x-height value. */ diff --git a/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/values/AnimatableLengthListValue.java b/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/values/AnimatableLengthListValue.java index 18031a993..8c005ac37 100644 --- a/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/values/AnimatableLengthListValue.java +++ b/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/values/AnimatableLengthListValue.java @@ -18,27 +18,28 @@ */ package io.sf.carte.echosvg.anim.values; -import org.w3c.dom.svg.SVGLength; +import org.w3c.css.om.unit.CSSUnit; import io.sf.carte.echosvg.anim.dom.AnimationTarget; /** * An SVG length list value in the animation system. * - * @author Cameron McCormack - * @author For later modifications, see Git history. + *
+ * Original author: Cameron McCormack. + * For later modifications, see Git history. + *
* @version $Id$ */ public class AnimatableLengthListValue extends AnimatableValue { /** - * The length types. + * The length types as in CSSUnit. */ protected short[] lengthTypes; /** - * The length values. These should be one of the constants defined in - * {@link SVGLength}. + * The length values. */ protected float[] lengthValues; @@ -117,7 +118,7 @@ public AnimatableValue interpolate(AnimatableValue result, AnimatableValue to, f || hasAcc && !AnimatableLengthValue.compatibleTypes(newLengthType, percentageInterpretation, accLengthList.lengthTypes[i], accLengthList.percentageInterpretation)) { newLengthValue = target.svgToUserSpace(newLengthValue, newLengthType, percentageInterpretation); - newLengthType = SVGLength.SVG_LENGTHTYPE_NUMBER; + newLengthType = CSSUnit.CSS_NUMBER; if (hasTo) { toV = to.target.svgToUserSpace(toLengthList.lengthValues[i], toLengthList.lengthTypes[i], toLengthList.percentageInterpretation); @@ -196,12 +197,12 @@ public String getCssText() { StringBuilder sb = new StringBuilder(); if (lengthValues.length > 0) { sb.append(formatNumber(lengthValues[0])); - sb.append(AnimatableLengthValue.UNITS[lengthTypes[0] - 1]); + sb.append(CSSUnit.dimensionUnitString(lengthTypes[0])); } for (int i = 1; i < lengthValues.length; i++) { sb.append(','); sb.append(formatNumber(lengthValues[i])); - sb.append(AnimatableLengthValue.UNITS[lengthTypes[i] - 1]); + sb.append(CSSUnit.dimensionUnitString(lengthTypes[i])); } return sb.toString(); } diff --git a/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/values/AnimatableLengthOrIdentValue.java b/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/values/AnimatableLengthOrIdentValue.java index 6c8abc4b6..6e9aa28de 100644 --- a/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/values/AnimatableLengthOrIdentValue.java +++ b/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/values/AnimatableLengthOrIdentValue.java @@ -18,7 +18,7 @@ */ package io.sf.carte.echosvg.anim.values; -import org.w3c.dom.svg.SVGLength; +import org.w3c.css.om.unit.CSSUnit; import io.sf.carte.echosvg.anim.dom.AnimationTarget; @@ -101,7 +101,7 @@ public float distanceTo(AnimatableValue other) { */ @Override public AnimatableValue getZeroValue() { - return new AnimatableLengthOrIdentValue(target, SVGLength.SVG_LENGTHTYPE_NUMBER, 0f, percentageInterpretation); + return new AnimatableLengthOrIdentValue(target, CSSUnit.CSS_NUMBER, 0f, percentageInterpretation); } /** diff --git a/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/values/AnimatableLengthValue.java b/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/values/AnimatableLengthValue.java index cd4b78892..398281e5e 100644 --- a/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/values/AnimatableLengthValue.java +++ b/echosvg-anim/src/main/java/io/sf/carte/echosvg/anim/values/AnimatableLengthValue.java @@ -18,7 +18,7 @@ */ package io.sf.carte.echosvg.anim.values; -import org.w3c.dom.svg.SVGLength; +import org.w3c.css.om.unit.CSSUnit; import io.sf.carte.echosvg.anim.dom.AnimationTarget; @@ -32,18 +32,12 @@ public class AnimatableLengthValue extends AnimatableValue { /** - * Length units. - */ - protected static final String[] UNITS = { "", "%", "em", "ex", "px", "cm", "mm", "in", "pt", "pc" }; - - /** - * The length type. + * The length type according to {@link CSSUnit}. */ protected short lengthType; /** - * The length value. This should be one of the constants defined in - * {@link SVGLength}. + * The length value. */ protected float lengthValue; @@ -97,7 +91,7 @@ public AnimatableValue interpolate(AnimatableValue result, AnimatableValue to, f if (!compatibleTypes(res.lengthType, res.percentageInterpretation, toLength.lengthType, toLength.percentageInterpretation)) { res.lengthValue = target.svgToUserSpace(res.lengthValue, res.lengthType, res.percentageInterpretation); - res.lengthType = SVGLength.SVG_LENGTHTYPE_NUMBER; + res.lengthType = CSSUnit.CSS_NUMBER; toValue = toLength.target.svgToUserSpace(toLength.lengthValue, toLength.lengthType, toLength.percentageInterpretation); } else { @@ -112,7 +106,7 @@ public AnimatableValue interpolate(AnimatableValue result, AnimatableValue to, f if (!compatibleTypes(res.lengthType, res.percentageInterpretation, accLength.lengthType, accLength.percentageInterpretation)) { res.lengthValue = target.svgToUserSpace(res.lengthValue, res.lengthType, res.percentageInterpretation); - res.lengthType = SVGLength.SVG_LENGTHTYPE_NUMBER; + res.lengthType = CSSUnit.CSS_NUMBER; accValue = accLength.target.svgToUserSpace(accLength.lengthValue, accLength.lengthType, accLength.percentageInterpretation); } else { @@ -137,9 +131,9 @@ public AnimatableValue interpolate(AnimatableValue result, AnimatableValue to, f * @param pi2 the second percentage interpretation type */ public static boolean compatibleTypes(short t1, short pi1, short t2, short pi2) { - return t1 == t2 && (t1 != SVGLength.SVG_LENGTHTYPE_PERCENTAGE || pi1 == pi2) - || t1 == SVGLength.SVG_LENGTHTYPE_NUMBER && t2 == SVGLength.SVG_LENGTHTYPE_PX - || t1 == SVGLength.SVG_LENGTHTYPE_PX && t2 == SVGLength.SVG_LENGTHTYPE_NUMBER; + return t1 == t2 && (t1 != CSSUnit.CSS_PERCENTAGE || pi1 == pi2) + || t1 == CSSUnit.CSS_NUMBER && t2 == CSSUnit.CSS_PX + || t1 == CSSUnit.CSS_PX && t2 == CSSUnit.CSS_NUMBER; } /** @@ -182,7 +176,7 @@ public float distanceTo(AnimatableValue other) { */ @Override public AnimatableValue getZeroValue() { - return new AnimatableLengthValue(target, SVGLength.SVG_LENGTHTYPE_NUMBER, 0f, percentageInterpretation); + return new AnimatableLengthValue(target, CSSUnit.CSS_NUMBER, 0f, percentageInterpretation); } /** @@ -192,7 +186,7 @@ public AnimatableValue getZeroValue() { */ @Override public String getCssText() { - return formatNumber(lengthValue) + UNITS[lengthType - 1]; + return formatNumber(lengthValue) + CSSUnit.dimensionUnitString(lengthType); } } diff --git a/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/AbstractGraphicsNodeBridge.java b/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/AbstractGraphicsNodeBridge.java index d77737eb2..b0f407712 100644 --- a/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/AbstractGraphicsNodeBridge.java +++ b/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/AbstractGraphicsNodeBridge.java @@ -606,4 +606,24 @@ public float getFontSize() { return CSSUtilities.getComputedStyle(e, SVGCSSEngine.FONT_SIZE_INDEX).getFloatValue(); } + /** + * Returns the line-height on the associated element. + */ + @Override + public float getLineHeight() { + return CSSUtilities.getComputedStyle(e, SVGCSSEngine.LINE_HEIGHT_INDEX).getFloatValue(); + } + + @Override + public float getRootFontSize() { + Element root = e.getOwnerDocument().getDocumentElement(); + return CSSUtilities.getComputedStyle(root, SVGCSSEngine.FONT_SIZE_INDEX).getFloatValue(); + } + + @Override + public float getRootLineHeight() { + Element root = e.getOwnerDocument().getDocumentElement(); + return CSSUtilities.getComputedStyle(root, SVGCSSEngine.LINE_HEIGHT_INDEX).getFloatValue(); + } + } diff --git a/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/AnimatableGenericSVGBridge.java b/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/AnimatableGenericSVGBridge.java index bb74dae71..6b98f6987 100644 --- a/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/AnimatableGenericSVGBridge.java +++ b/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/AnimatableGenericSVGBridge.java @@ -135,6 +135,21 @@ public float getFontSize() { return 0f; } + @Override + public float getLineHeight() { + return 0f; + } + + @Override + public float getRootFontSize() { + return 0f; + } + + @Override + public float getRootLineHeight() { + return 0f; + } + // BridgeUpdateHandler /////////////////////////////////////////////////// @Override diff --git a/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGAnimationElementBridge.java b/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGAnimationElementBridge.java index de11b0e5a..7df4f0274 100644 --- a/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGAnimationElementBridge.java +++ b/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGAnimationElementBridge.java @@ -428,11 +428,26 @@ public float getViewportHeight() { @Override public float getFontSize() { - return 0; + return 0f; + } + + @Override + public float getLineHeight() { + return 0f; + } + + @Override + public float getRootFontSize() { + return 0f; + } + + @Override + public float getRootLineHeight() { + return 0f; } public float svgToUserSpace(float v, int type, int pcInterp) { - return 0; + return 0f; } /** 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 60e3cadcc..521928dde 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 @@ -35,7 +35,6 @@ import org.w3c.dom.css.CSSStyleDeclaration; import org.w3c.dom.events.EventTarget; import org.w3c.dom.svg.SVGAngle; -import org.w3c.dom.svg.SVGLength; import org.w3c.dom.svg.SVGPreserveAspectRatio; import io.sf.carte.doc.style.css.CSSValue.CssType; @@ -1406,7 +1405,7 @@ protected static class AnimatableLengthValueFactory implements Factory { @Override public void startLength() throws ParseException { - type = SVGLength.SVG_LENGTHTYPE_NUMBER; + type = CSSUnit.CSS_NUMBER; } @Override @@ -1415,48 +1414,8 @@ public void lengthValue(float v) throws ParseException { } @Override - public void em() throws ParseException { - type = SVGLength.SVG_LENGTHTYPE_EMS; - } - - @Override - public void ex() throws ParseException { - type = SVGLength.SVG_LENGTHTYPE_EXS; - } - - @Override - public void in() throws ParseException { - type = SVGLength.SVG_LENGTHTYPE_IN; - } - - @Override - public void cm() throws ParseException { - type = SVGLength.SVG_LENGTHTYPE_CM; - } - - @Override - public void mm() throws ParseException { - type = SVGLength.SVG_LENGTHTYPE_MM; - } - - @Override - public void pc() throws ParseException { - type = SVGLength.SVG_LENGTHTYPE_PC; - } - - @Override - public void pt() throws ParseException { - type = SVGLength.SVG_LENGTHTYPE_PT; - } - - @Override - public void px() throws ParseException { - type = SVGLength.SVG_LENGTHTYPE_PX; - } - - @Override - public void percentage() throws ParseException { - type = SVGLength.SVG_LENGTHTYPE_PERCENTAGE; + protected void setUnit(short unit) { + type = unit; } @Override diff --git a/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGDescriptiveElementBridge.java b/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGDescriptiveElementBridge.java index 557bb4180..e24ccfe2c 100644 --- a/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGDescriptiveElementBridge.java +++ b/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGDescriptiveElementBridge.java @@ -159,7 +159,22 @@ public float getViewportHeight() { @Override public float getFontSize() { - return 0; + return 0f; + } + + @Override + public float getLineHeight() { + return 0f; + } + + @Override + public float getRootFontSize() { + return 0f; + } + + @Override + public float getRootLineHeight() { + return 0f; } } diff --git a/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGDocumentBridge.java b/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGDocumentBridge.java index 0e69203db..47c127045 100644 --- a/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGDocumentBridge.java +++ b/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGDocumentBridge.java @@ -245,7 +245,22 @@ public float getViewportHeight() { @Override public float getFontSize() { - return 0; + return 0f; + } + + @Override + public float getLineHeight() { + return 0f; + } + + @Override + public float getRootFontSize() { + return 0f; + } + + @Override + public float getRootLineHeight() { + return 0f; } } diff --git a/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGTextElementBridge.java b/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGTextElementBridge.java index 6f1de47a0..4aa3ebfb1 100644 --- a/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGTextElementBridge.java +++ b/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGTextElementBridge.java @@ -1926,6 +1926,23 @@ public float getFontSize() { return CSSUtilities.getComputedStyle(e, SVGCSSEngine.FONT_SIZE_INDEX).getFloatValue(); } + @Override + public float getLineHeight() { + return CSSUtilities.getComputedStyle(e, SVGCSSEngine.LINE_HEIGHT_INDEX).getFloatValue(); + } + + @Override + public float getRootFontSize() { + Element root = e.getOwnerDocument().getDocumentElement(); + return CSSUtilities.getComputedStyle(root, SVGCSSEngine.FONT_SIZE_INDEX).getFloatValue(); + } + + @Override + public float getRootLineHeight() { + Element root = e.getOwnerDocument().getDocumentElement(); + return CSSUtilities.getComputedStyle(root, SVGCSSEngine.LINE_HEIGHT_INDEX).getFloatValue(); + } + } /** diff --git a/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/UnitProcessor.java b/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/UnitProcessor.java index 07bcff3a6..4efc7948d 100644 --- a/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/UnitProcessor.java +++ b/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/UnitProcessor.java @@ -150,7 +150,7 @@ public static float svgLengthToObjectBoundingBox(String s, String attr, short d, */ public static float svgToObjectBoundingBox(String s, String attr, short d, Context ctx) { try { - return io.sf.carte.echosvg.parser.UnitProcessor.svgToObjectBoundingBox(s, attr, d, ctx); + return io.sf.carte.echosvg.parser.UnitProcessor.cssToObjectBoundingBox(s, attr, d, ctx); } catch (ParseException pEx) { throw new BridgeException(getBridgeContext(ctx), ctx.getElement(), pEx, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED, new Object[] { attr, s, pEx }); @@ -259,7 +259,7 @@ public static float svgLengthToUserSpace(String s, String attr, short d, Context */ public static float svgToUserSpace(String s, String attr, short d, Context ctx) { try { - return io.sf.carte.echosvg.parser.UnitProcessor.svgToUserSpace(s, attr, d, ctx); + return io.sf.carte.echosvg.parser.UnitProcessor.cssToUserSpace(s, attr, d, ctx); } catch (ParseException pEx) { throw new BridgeException(getBridgeContext(ctx), ctx.getElement(), pEx, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED, new Object[] { attr, s, pEx, }); @@ -323,6 +323,23 @@ public float getFontSize() { return CSSUtilities.getComputedStyle(e, SVGCSSEngine.FONT_SIZE_INDEX).getFloatValue(); } + @Override + public float getLineHeight() { + return CSSUtilities.getComputedStyle(e, SVGCSSEngine.LINE_HEIGHT_INDEX).getFloatValue(); + } + + @Override + public float getRootFontSize() { + Element root = e.getOwnerDocument().getDocumentElement(); + return CSSUtilities.getComputedStyle(root, SVGCSSEngine.FONT_SIZE_INDEX).getFloatValue(); + } + + @Override + public float getRootLineHeight() { + Element root = e.getOwnerDocument().getDocumentElement(); + return CSSUtilities.getComputedStyle(root, SVGCSSEngine.LINE_HEIGHT_INDEX).getFloatValue(); + } + /** * Returns the x-height value. */ 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 aa26e5576..d2201336c 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 @@ -259,14 +259,14 @@ public Value computeValue(CSSStylableElement elt, String pseudo, CSSEngine engin v = value.getFloatValue(); return new FloatValue(CSSUnit.CSS_PX, v * - engine.getCSSContext().getViewport(elt).getWidth() * 0.01f); + engine.getCSSContext().getViewport(elt).getWidth() / 100f); case CSSUnit.CSS_VH: sm.putViewportRelative(idx, true); v = value.getFloatValue(); return new FloatValue(CSSUnit.CSS_PX, v * - engine.getCSSContext().getViewport(elt).getHeight() * 0.01f); + engine.getCSSContext().getViewport(elt).getHeight() / 100f); case CSSUnit.CSS_VMIN: sm.putViewportRelative(idx, true); @@ -276,7 +276,7 @@ public Value computeValue(CSSStylableElement elt, String pseudo, CSSEngine engin float w = vp.getWidth(); float h = vp.getHeight(); float min = Math.min(w, h); - return new FloatValue(CSSUnit.CSS_PX, v * min * 0.01f); + return new FloatValue(CSSUnit.CSS_PX, v * min / 100f); case CSSUnit.CSS_VMAX: sm.putViewportRelative(idx, true); @@ -286,7 +286,7 @@ public Value computeValue(CSSStylableElement elt, String pseudo, CSSEngine engin w = vp.getWidth(); h = vp.getHeight(); float max = Math.max(w, h); - return new FloatValue(CSSUnit.CSS_PX, v * max * 0.01f); + return new FloatValue(CSSUnit.CSS_PX, v * max / 100f); case CSSUnit.CSS_INVALID: case CSSUnit.CSS_OTHER: diff --git a/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/DefaultLengthHandler.java b/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/DefaultLengthHandler.java index 10c47d1f8..98ed55e81 100644 --- a/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/DefaultLengthHandler.java +++ b/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/DefaultLengthHandler.java @@ -18,6 +18,8 @@ */ package io.sf.carte.echosvg.parser; +import org.w3c.css.om.unit.CSSUnit; + /** * This class provides an adapter for LengthHandler * @@ -27,11 +29,6 @@ */ public class DefaultLengthHandler implements LengthHandler { - /** - * The only instance of this class. - */ - public static final LengthHandler INSTANCE = new DefaultLengthHandler(); - /** * This class does not need to be instantiated. */ @@ -52,67 +49,77 @@ public void startLength() throws ParseException { public void lengthValue(float v) throws ParseException { } - /** - * Implements {@link LengthHandler#em()}. - */ @Override public void em() throws ParseException { + setUnit(CSSUnit.CSS_EM); } - /** - * Implements {@link LengthHandler#ex()}. - */ @Override public void ex() throws ParseException { + setUnit(CSSUnit.CSS_EX); + } + + @Override + public void lh() throws ParseException { + setUnit(CSSUnit.CSS_LH); } - /** - * Implements {@link LengthHandler#in()}. - */ @Override public void in() throws ParseException { + setUnit(CSSUnit.CSS_IN); } - /** - * Implements {@link LengthHandler#cm()}. - */ @Override public void cm() throws ParseException { + setUnit(CSSUnit.CSS_CM); } - /** - * Implements {@link LengthHandler#mm()}. - */ @Override public void mm() throws ParseException { + setUnit(CSSUnit.CSS_MM); } - /** - * Implements {@link LengthHandler#pc()}. - */ @Override public void pc() throws ParseException { + setUnit(CSSUnit.CSS_PC); } - /** - * Implements {@link LengthHandler#pt()}. - */ @Override public void pt() throws ParseException { + setUnit(CSSUnit.CSS_PT); } - /** - * Implements {@link LengthHandler#px()}. - */ @Override public void px() throws ParseException { + setUnit(CSSUnit.CSS_PX); } - /** - * Implements {@link LengthHandler#percentage()}. - */ @Override public void percentage() throws ParseException { + setUnit(CSSUnit.CSS_PERCENTAGE); + } + + @Override + public void vh() throws ParseException { + setUnit(CSSUnit.CSS_VH); + } + + @Override + public void vw() throws ParseException { + setUnit(CSSUnit.CSS_VW); + } + + @Override + public void vmax() throws ParseException { + setUnit(CSSUnit.CSS_VMAX); + } + + @Override + public void vmin() throws ParseException { + setUnit(CSSUnit.CSS_VMIN); + } + + protected void setUnit(short unit) { } /** diff --git a/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/LengthArrayProducer.java b/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/LengthArrayProducer.java index 0dcd5c410..51ce6fb82 100644 --- a/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/LengthArrayProducer.java +++ b/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/LengthArrayProducer.java @@ -21,7 +21,7 @@ import java.util.Iterator; import java.util.LinkedList; -import org.w3c.dom.svg.SVGLength; +import org.w3c.css.om.unit.CSSUnit; /** * A handler class that generates an array of shorts and an array floats from @@ -87,7 +87,7 @@ public float[] getLengthValueArray() { /** * Invoked when the length list attribute starts. * - * @exception ParseException if an error occures while processing the number + * @exception ParseException if an error occurs while processing the number * list. */ @Override @@ -103,7 +103,7 @@ public void startLengthList() throws ParseException { /** * Invoked when a float value has been parsed. * - * @exception ParseException if an error occures while processing the number + * @exception ParseException if an error occurs while processing the number */ public void numberValue(float v) throws ParseException { } @@ -128,7 +128,7 @@ public void lengthValue(float val) throws ParseException { */ @Override public void startLength() throws ParseException { - currentUnit = SVGLength.SVG_LENGTHTYPE_NUMBER; + currentUnit = CSSUnit.CSS_NUMBER; } /** @@ -140,82 +140,15 @@ public void endLength() throws ParseException { count++; } - /** - * Implements {@link LengthHandler#em()}. - */ - @Override - public void em() throws ParseException { - currentUnit = SVGLength.SVG_LENGTHTYPE_EMS; - } - - /** - * Implements {@link LengthHandler#ex()}. - */ - @Override - public void ex() throws ParseException { - currentUnit = SVGLength.SVG_LENGTHTYPE_EXS; - } - - /** - * Implements {@link LengthHandler#in()}. - */ - @Override - public void in() throws ParseException { - currentUnit = SVGLength.SVG_LENGTHTYPE_IN; - } - - /** - * Implements {@link LengthHandler#cm()}. - */ - @Override - public void cm() throws ParseException { - currentUnit = SVGLength.SVG_LENGTHTYPE_CM; - } - - /** - * Implements {@link LengthHandler#mm()}. - */ - @Override - public void mm() throws ParseException { - currentUnit = SVGLength.SVG_LENGTHTYPE_MM; - } - - /** - * Implements {@link LengthHandler#pc()}. - */ - @Override - public void pc() throws ParseException { - currentUnit = SVGLength.SVG_LENGTHTYPE_PC; - } - - /** - * Implements {@link LengthHandler#pt()}. - */ - @Override - public void pt() throws ParseException { - currentUnit = SVGLength.SVG_LENGTHTYPE_PT; - } - - /** - * Implements {@link LengthHandler#px()}. - */ - @Override - public void px() throws ParseException { - currentUnit = SVGLength.SVG_LENGTHTYPE_PX; - } - - /** - * Implements {@link LengthHandler#percentage()}. - */ @Override - public void percentage() throws ParseException { - currentUnit = SVGLength.SVG_LENGTHTYPE_PERCENTAGE; + protected void setUnit(short unit) { + currentUnit = unit; } /** * Invoked when the length list attribute ends. * - * @exception ParseException if an error occures while processing the number + * @exception ParseException if an error occurs while processing the number * list. */ @Override diff --git a/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/LengthHandler.java b/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/LengthHandler.java index 89a0f41a5..d585fa65d 100644 --- a/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/LengthHandler.java +++ b/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/LengthHandler.java @@ -19,11 +19,13 @@ package io.sf.carte.echosvg.parser; /** - * This interface must be implemented and then registred as the handler of a + * This interface must be implemented and then registered as the handler of a *LengthParser
instance in order to be notified of parsing events.
*
- * @author Stephane Hillion
- * @author For later modifications, see Git history.
+ * + * Original author: Stephane Hillion. + * For later modifications, see Git history. + *
* @version $Id$ */ public interface LengthHandler { @@ -31,84 +33,119 @@ public interface LengthHandler { /** * Invoked when the length attribute starts. * - * @exception ParseException if an error occures while processing the length + * @exception ParseException if an error occurs while processing the length */ void startLength() throws ParseException; /** * Invoked when a float value has been parsed. * - * @exception ParseException if an error occures while processing the length + * @exception ParseException if an error occurs while processing the length */ void lengthValue(float v) throws ParseException; /** * Invoked when 'em' has been parsed. * - * @exception ParseException if an error occures while processing the length + * @exception ParseException if an error occurs while processing the length */ void em() throws ParseException; /** * Invoked when 'ex' has been parsed. * - * @exception ParseException if an error occures while processing the length + * @exception ParseException if an error occurs while processing the length */ void ex() throws ParseException; + /** + * Invoked when 'lh' has been parsed. + * + * @exception ParseException if an error occurs while processing the length + */ + void lh() throws ParseException; + /** * Invoked when 'in' has been parsed. * - * @exception ParseException if an error occures while processing the length + * @exception ParseException if an error occurs while processing the length */ void in() throws ParseException; /** * Invoked when 'cm' has been parsed. * - * @exception ParseException if an error occures while processing the length + * @exception ParseException if an error occurs while processing the length */ void cm() throws ParseException; /** * Invoked when 'mm' has been parsed. * - * @exception ParseException if an error occures while processing the length + * @exception ParseException if an error occurs while processing the length */ void mm() throws ParseException; /** * Invoked when 'pc' has been parsed. * - * @exception ParseException if an error occures while processing the length + * @exception ParseException if an error occurs while processing the length */ void pc() throws ParseException; /** * Invoked when 'pt' has been parsed. * - * @exception ParseException if an error occures while processing the length + * @exception ParseException if an error occurs while processing the length */ void pt() throws ParseException; /** * Invoked when 'px' has been parsed. * - * @exception ParseException if an error occures while processing the length + * @exception ParseException if an error occurs while processing the length */ void px() throws ParseException; /** * Invoked when '%' has been parsed. * - * @exception ParseException if an error occures while processing the length + * @exception ParseException if an error occurs while processing the length */ void percentage() throws ParseException; + /** + * Invoked when 'vh' has been parsed. + * + * @exception ParseException if an error occurs while processing the length + */ + void vh() throws ParseException; + + /** + * Invoked when 'vw' has been parsed. + * + * @exception ParseException if an error occurs while processing the length + */ + void vw() throws ParseException; + + /** + * Invoked when 'vmax' has been parsed. + * + * @exception ParseException if an error occurs while processing the length + */ + void vmax() throws ParseException; + + /** + * Invoked when 'vmin' has been parsed. + * + * @exception ParseException if an error occurs while processing the length + */ + void vmin() throws ParseException; + /** * Invoked when the length attribute ends. * - * @exception ParseException if an error occures while processing the length + * @exception ParseException if an error occurs while processing the length */ void endLength() throws ParseException; diff --git a/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/LengthParser.java b/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/LengthParser.java index 612ee1791..5779b2c7c 100644 --- a/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/LengthParser.java +++ b/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/LengthParser.java @@ -29,6 +29,11 @@ */ public class LengthParser extends AbstractParser { + /** + * The instance of a no-op LengthHandler. + */ + private static final LengthHandler NOOP_LENGTH_HANDLER_INSTANCE = new DefaultLengthHandler(); + /** * The length handler used to report parse events. */ @@ -38,7 +43,7 @@ public class LengthParser extends AbstractParser { * Creates a new LengthParser. */ public LengthParser() { - lengthHandler = DefaultLengthHandler.INSTANCE; + lengthHandler = NOOP_LENGTH_HANDLER_INSTANCE; } /** @@ -423,6 +428,15 @@ protected void parseLength() throws ParseException, IOException { lengthHandler.cm(); current = reader.read(); break; + case 'l': + current = reader.read(); + if (current != 'h') { + reportCharacterExpectedError('l', current); + break; + } + lengthHandler.lh(); + current = reader.read(); + break; case 'm': current = reader.read(); if (current != 'm') { @@ -436,6 +450,45 @@ protected void parseLength() throws ParseException, IOException { lengthHandler.percentage(); current = reader.read(); break; + case 'v': + current = reader.read(); + switch (current) { + case 'w': + lengthHandler.vw(); + current = reader.read(); + break; + case 'h': + lengthHandler.vh(); + current = reader.read(); + break; + case 'm': + switch (current) { + case 'i': + current = reader.read(); + if (current != 'n') { + reportCharacterExpectedError('n', current); + break; + } + lengthHandler.vmin(); + current = reader.read(); + break; + case 'a': + current = reader.read(); + if (current != 'x') { + reportCharacterExpectedError('x', current); + break; + } + lengthHandler.vmax(); + current = reader.read(); + break; + default: + reportUnexpectedCharacterError(current); + } + break; + default: + reportUnexpectedCharacterError(current); + } + break; } } diff --git a/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/UnitProcessor.java b/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/UnitProcessor.java index d7f9cb77f..2b968b681 100644 --- a/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/UnitProcessor.java +++ b/echosvg-parser/src/main/java/io/sf/carte/echosvg/parser/UnitProcessor.java @@ -18,8 +18,8 @@ */ package io.sf.carte.echosvg.parser; +import org.w3c.css.om.unit.CSSUnit; import org.w3c.dom.Element; -import org.w3c.dom.svg.SVGLength; /** * This class provides methods to convert SVG length and coordinate to float in @@ -67,12 +67,12 @@ protected UnitProcessor() { * @param d the direction of the value * @param ctx the context used to resolve relative value */ - public static float svgToObjectBoundingBox(String s, String attr, short d, Context ctx) throws ParseException { + public static float cssToObjectBoundingBox(String s, String attr, short d, Context ctx) throws ParseException { LengthParser lengthParser = new LengthParser(); UnitResolver ur = new UnitResolver(); lengthParser.setLengthHandler(ur); lengthParser.parse(s); - return svgToObjectBoundingBox(ur.value, ur.unit, d, ctx); + return cssToObjectBoundingBox(ur.value, ur.unit, d, ctx); } /** @@ -80,32 +80,23 @@ public static float svgToObjectBoundingBox(String s, String attr, short d, Conte * units. * * @param value the value - * @param type the type of the value + * @param type the type of the value according to CSSUnit * @param d the direction of the value * @param ctx the context used to resolve relative value */ - public static float svgToObjectBoundingBox(float value, short type, short d, Context ctx) { + public static float cssToObjectBoundingBox(float value, short type, short d, Context ctx) { switch (type) { - case SVGLength.SVG_LENGTHTYPE_NUMBER: + case CSSUnit.CSS_NUMBER: // as is return value; - case SVGLength.SVG_LENGTHTYPE_PERCENTAGE: + case CSSUnit.CSS_PERCENTAGE: // If a percentage value is used, it is converted to a // 'bounding box' space coordinate by division by 100 return value / 100f; - case SVGLength.SVG_LENGTHTYPE_PX: - case SVGLength.SVG_LENGTHTYPE_MM: - case SVGLength.SVG_LENGTHTYPE_CM: - case SVGLength.SVG_LENGTHTYPE_IN: - case SVGLength.SVG_LENGTHTYPE_PT: - case SVGLength.SVG_LENGTHTYPE_PC: - case SVGLength.SVG_LENGTHTYPE_EMS: - case SVGLength.SVG_LENGTHTYPE_EXS: + default: // FIXME: resolve units in userSpace but consider them // in the objectBoundingBox coordinate system - return svgToUserSpace(value, type, d, ctx); - default: - throw new IllegalArgumentException("Length has unknown type"); + return cssToUserSpace(value, type, d, ctx); } } @@ -121,12 +112,12 @@ public static float svgToObjectBoundingBox(float value, short type, short d, Con * @param d the direction of the coordinate * @param ctx the context used to resolve relative value */ - public static float svgToUserSpace(String s, String attr, short d, Context ctx) throws ParseException { + public static float cssToUserSpace(String s, String attr, short d, Context ctx) throws ParseException { LengthParser lengthParser = new LengthParser(); UnitResolver ur = new UnitResolver(); lengthParser.setLengthHandler(ur); lengthParser.parse(s); - return svgToUserSpace(ur.value, ur.unit, d, ctx); + return cssToUserSpace(ur.value, ur.unit, d, ctx); } /** @@ -134,31 +125,44 @@ public static float svgToUserSpace(String s, String attr, short d, Context ctx) * units. * * @param v the value to convert - * @param type the type of the value + * @param type the type of the value according to CSSUnit * @param d HORIZONTAL_LENGTH, VERTICAL_LENGTH, or OTHER_LENGTH * @param ctx the context used to resolve relative value + * @return the value in user space units. */ - public static float svgToUserSpace(float v, short type, short d, Context ctx) { + public static float cssToUserSpace(float v, short type, short d, Context ctx) { switch (type) { - case SVGLength.SVG_LENGTHTYPE_NUMBER: - case SVGLength.SVG_LENGTHTYPE_PX: + case CSSUnit.CSS_NUMBER: + case CSSUnit.CSS_PX: return v; - case SVGLength.SVG_LENGTHTYPE_MM: + case CSSUnit.CSS_PERCENTAGE: + return percentagesToPixels(v, d, ctx); + case CSSUnit.CSS_EM: + return emsToPixels(v, d, ctx); + case CSSUnit.CSS_EX: + return exsToPixels(v, d, ctx); + case CSSUnit.CSS_LH: + return lhToPixels(v, d, ctx); + case CSSUnit.CSS_VW: + return vwToPixels(v, d, ctx); + case CSSUnit.CSS_VH: + return vhToPixels(v, d, ctx); + case CSSUnit.CSS_VMIN: + return vminToPixels(v, d, ctx); + case CSSUnit.CSS_VMAX: + return vmaxToPixels(v, d, ctx); + case CSSUnit.CSS_MM: return v * 3.779527559055f; // 96 / 25.4 - case SVGLength.SVG_LENGTHTYPE_CM: + case CSSUnit.CSS_CM: return v * 37.79527559055f; // 96 / 2.54 - case SVGLength.SVG_LENGTHTYPE_IN: + case CSSUnit.CSS_IN: return v * 96f; - case SVGLength.SVG_LENGTHTYPE_PT: + case CSSUnit.CSS_PT: return v / 0.75f; // Mult. by 96 / 72 - case SVGLength.SVG_LENGTHTYPE_PC: + case CSSUnit.CSS_PC: return v * 16f; // 96 / 6 - case SVGLength.SVG_LENGTHTYPE_EMS: - return emsToPixels(v, d, ctx); - case SVGLength.SVG_LENGTHTYPE_EXS: - return exsToPixels(v, d, ctx); - case SVGLength.SVG_LENGTHTYPE_PERCENTAGE: - return percentagesToPixels(v, d, ctx); + case CSSUnit.CSS_QUARTER_MM: + return v * 0.94488188976f; // 96 / 25.4 / 4 default: throw new IllegalArgumentException("Length has unknown type"); } @@ -169,30 +173,43 @@ public static float svgToUserSpace(float v, short type, short d, Context ctx) { * units. * * @param v the value to convert - * @param type the type of the value + * @param type the type of the value according to CSSUnit * @param d HORIZONTAL_LENGTH, VERTICAL_LENGTH, or OTHER_LENGTH * @param ctx the context used to resolve relative value + * @return the value in the given unit. */ - public static float userSpaceToSVG(float v, short type, short d, Context ctx) { + public static float userSpaceToCSS(float v, short type, short d, Context ctx) { switch (type) { - case SVGLength.SVG_LENGTHTYPE_NUMBER: - case SVGLength.SVG_LENGTHTYPE_PX: + case CSSUnit.CSS_NUMBER: + case CSSUnit.CSS_PX: return v; - case SVGLength.SVG_LENGTHTYPE_MM: + case CSSUnit.CSS_MM: return v * 0.26458333333333f; // 25.4/96 - case SVGLength.SVG_LENGTHTYPE_CM: + case CSSUnit.CSS_CM: return v * 0.026458333333333f; // 2.54/96 - case SVGLength.SVG_LENGTHTYPE_IN: + case CSSUnit.CSS_IN: return v / 96f; - case SVGLength.SVG_LENGTHTYPE_PT: + case CSSUnit.CSS_PT: return v * 0.75f; // 72/96 - case SVGLength.SVG_LENGTHTYPE_PC: + case CSSUnit.CSS_PC: return v / 16f; - case SVGLength.SVG_LENGTHTYPE_EMS: + case CSSUnit.CSS_QUARTER_MM: + return v * 1.0583333333333f; // 25.4*4/96 + case CSSUnit.CSS_EM: return pixelsToEms(v, d, ctx); - case SVGLength.SVG_LENGTHTYPE_EXS: + case CSSUnit.CSS_EX: return pixelsToExs(v, d, ctx); - case SVGLength.SVG_LENGTHTYPE_PERCENTAGE: + case CSSUnit.CSS_LH: + return pixelsToLh(v, d, ctx); + case CSSUnit.CSS_VW: + return pixelsToVw(v, d, ctx); + case CSSUnit.CSS_VH: + return pixelsToVh(v, d, ctx); + case CSSUnit.CSS_VMIN: + return pixelsToVmin(v, d, ctx); + case CSSUnit.CSS_VMAX: + return pixelsToVmax(v, d, ctx); + case CSSUnit.CSS_PERCENTAGE: return pixelsToPercentages(v, d, ctx); default: throw new IllegalArgumentException("Length has unknown type"); @@ -293,10 +310,116 @@ protected static float exsToPixels(float v, short d, Context ctx) { return v * xh * ctx.getFontSize(); } + /** + * Converts user units to lh units. + * + * @param v the value to convert + * @param d HORIZONTAL_LENGTH, VERTICAL_LENGTH, or OTHER_LENGTH + * @param ctx the context + */ + protected static float pixelsToLh(float v, short d, Context ctx) { + return v / ctx.getLineHeight(); + } + + /** + * Converts lh units to user units. + * + * @param v the value to convert + * @param d HORIZONTAL_LENGTH, VERTICAL_LENGTH, or OTHER_LENGTH + * @param ctx the context + */ + protected static float lhToPixels(float v, short d, Context ctx) { + return v * ctx.getLineHeight(); + } + + /** + * Converts user units to rem units. + * + * @param v the value to convert + * @param d HORIZONTAL_LENGTH, VERTICAL_LENGTH, or OTHER_LENGTH + * @param ctx the context + */ + protected static float pixelsToRem(float v, short d, Context ctx) { + return v / ctx.getRootFontSize(); + } + + /** + * Converts rem units to user units. + * + * @param v the value to convert + * @param d HORIZONTAL_LENGTH, VERTICAL_LENGTH, or OTHER_LENGTH + * @param ctx the context + */ + protected static float remToPixels(float v, short d, Context ctx) { + return v * ctx.getRootFontSize(); + } + + /** + * Converts user units to rlh units. + * + * @param v the value to convert + * @param d HORIZONTAL_LENGTH, VERTICAL_LENGTH, or OTHER_LENGTH + * @param ctx the context + */ + protected static float pixelsToRlh(float v, short d, Context ctx) { + return v / ctx.getRootLineHeight(); + } + + /** + * Converts rlh units to user units. + * + * @param v the value to convert + * @param d HORIZONTAL_LENGTH, VERTICAL_LENGTH, or OTHER_LENGTH + * @param ctx the context + */ + protected static float rlhToPixels(float v, short d, Context ctx) { + return v * ctx.getRootLineHeight(); + } + + private static float pixelsToVw(float v, short d, Context ctx) { + return v / ctx.getViewportWidth() * 100f; + } + + private static float pixelsToVh(float v, short d, Context ctx) { + return v / ctx.getViewportHeight() * 100f; + } + + private static float pixelsToVmax(float v, short d, Context ctx) { + float w = ctx.getViewportWidth(); + float h = ctx.getViewportHeight(); + return v / Math.max(w, h) * 100f; + } + + private static float pixelsToVmin(float v, short d, Context ctx) { + float w = ctx.getViewportWidth(); + float h = ctx.getViewportHeight(); + return v / Math.min(w, h) * 100f; + } + + private static float vwToPixels(float v, short d, Context ctx) { + return v * ctx.getViewportWidth() / 100f; + } + + private static float vhToPixels(float v, short d, Context ctx) { + return v * ctx.getViewportHeight() / 100f; + } + + private static float vmaxToPixels(float v, short d, Context ctx) { + float w = ctx.getViewportWidth(); + float h = ctx.getViewportHeight(); + return v * Math.max(w, h) / 100f; + } + + private static float vminToPixels(float v, short d, Context ctx) { + float w = ctx.getViewportWidth(); + float h = ctx.getViewportHeight(); + return v * Math.min(w, h) / 100f; + } + /** * A LengthHandler that convert units. */ - public static class UnitResolver implements LengthHandler { + public static class UnitResolver extends DefaultLengthHandler { /** * The length value. @@ -306,7 +429,7 @@ public static class UnitResolver implements LengthHandler { /** * The length type. */ - public short unit = SVGLength.SVG_LENGTHTYPE_NUMBER; + public short unit = CSSUnit.CSS_NUMBER; /** * Implements {@link LengthHandler#startLength()}. @@ -323,76 +446,9 @@ public void lengthValue(float v) throws ParseException { this.value = v; } - /** - * Implements {@link LengthHandler#em()}. - */ - @Override - public void em() throws ParseException { - this.unit = SVGLength.SVG_LENGTHTYPE_EMS; - } - - /** - * Implements {@link LengthHandler#ex()}. - */ - @Override - public void ex() throws ParseException { - this.unit = SVGLength.SVG_LENGTHTYPE_EXS; - } - - /** - * Implements {@link LengthHandler#in()}. - */ - @Override - public void in() throws ParseException { - this.unit = SVGLength.SVG_LENGTHTYPE_IN; - } - - /** - * Implements {@link LengthHandler#cm()}. - */ - @Override - public void cm() throws ParseException { - this.unit = SVGLength.SVG_LENGTHTYPE_CM; - } - - /** - * Implements {@link LengthHandler#mm()}. - */ - @Override - public void mm() throws ParseException { - this.unit = SVGLength.SVG_LENGTHTYPE_MM; - } - - /** - * Implements {@link LengthHandler#pc()}. - */ - @Override - public void pc() throws ParseException { - this.unit = SVGLength.SVG_LENGTHTYPE_PC; - } - - /** - * Implements {@link LengthHandler#pt()}. - */ @Override - public void pt() throws ParseException { - this.unit = SVGLength.SVG_LENGTHTYPE_PT; - } - - /** - * Implements {@link LengthHandler#px()}. - */ - @Override - public void px() throws ParseException { - this.unit = SVGLength.SVG_LENGTHTYPE_PX; - } - - /** - * Implements {@link LengthHandler#percentage()}. - */ - @Override - public void percentage() throws ParseException { - this.unit = SVGLength.SVG_LENGTHTYPE_PERCENTAGE; + protected void setUnit(short unit) { + this.unit = unit; } /** @@ -429,6 +485,21 @@ public interface Context { */ float getXHeight(); + /** + * Returns the line-height value. + */ + float getLineHeight(); + + /** + * Returns the font-size value of the :root element. + */ + float getRootFontSize(); + + /** + * Returns the line-height value of the :root element. + */ + float getRootLineHeight(); + /** * Returns the viewport width used to compute units. */ diff --git a/echosvg-svg-dom/src/main/java/io/sf/carte/echosvg/dom/svg/SVGContext.java b/echosvg-svg-dom/src/main/java/io/sf/carte/echosvg/dom/svg/SVGContext.java index 564b86013..d3aa31022 100644 --- a/echosvg-svg-dom/src/main/java/io/sf/carte/echosvg/dom/svg/SVGContext.java +++ b/echosvg-svg-dom/src/main/java/io/sf/carte/echosvg/dom/svg/SVGContext.java @@ -109,4 +109,19 @@ default float getPixelToMM() { */ float getFontSize(); + /** + * Returns the line-height on the associated element. + */ + float getLineHeight(); + + /** + * Returns the font-size on the {@code :root} element. + */ + float getRootFontSize(); + + /** + * Returns the line-height on the {@code :root} element. + */ + float getRootLineHeight(); + } diff --git a/echosvg-test/src/test/java/io/sf/carte/echosvg/parser/test/LengthParserTest.java b/echosvg-test/src/test/java/io/sf/carte/echosvg/parser/test/LengthParserTest.java index 30fc724f3..757fbb131 100644 --- a/echosvg-test/src/test/java/io/sf/carte/echosvg/parser/test/LengthParserTest.java +++ b/echosvg-test/src/test/java/io/sf/carte/echosvg/parser/test/LengthParserTest.java @@ -103,6 +103,11 @@ public void ex() throws ParseException { buffer.append("ex"); } + @Override + public void lh() throws ParseException { + buffer.append("lh"); + } + @Override public void in() throws ParseException { buffer.append("in"); @@ -138,6 +143,26 @@ public void percentage() throws ParseException { buffer.append("%"); } + @Override + public void vh() throws ParseException { + buffer.append("vh"); + } + + @Override + public void vw() throws ParseException { + buffer.append("vw"); + } + + @Override + public void vmax() throws ParseException { + buffer.append("vmax"); + } + + @Override + public void vmin() throws ParseException { + buffer.append("vmin"); + } + @Override public void endLength() throws ParseException { resultLength = buffer.toString(); diff --git a/gradle.properties b/gradle.properties index 6b7b86c05..a7555886c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ xmlDtdVersion=4.3 rhinoVersion=1.7.15 legacyColorsVersion=1.0 domViewVersion=1.0 -svgomVersion=1.1.1 +svgomVersion=1.1.2 xmlApisVersion=1.4.01 commonsIOVersion=2.16.1 htmlParserVersion=1.4.16