Skip to content

Commit

Permalink
Follow-up to 54b14d6: parse rem, rex, rlh units with native parser
Browse files Browse the repository at this point in the history
carlosame committed Oct 19, 2024
1 parent 5f71fd5 commit 2ad9989
Showing 14 changed files with 243 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -357,6 +357,11 @@ public float getRootFontSize() {
return getAssociatedElement().getSVGContext().getRootFontSize();
}

@Override
public float getRootXHeight() {
return 0.5f;
}

@Override
public float getRootLineHeight() {
return getAssociatedElement().getSVGContext().getRootLineHeight();
Original file line number Diff line number Diff line change
@@ -912,6 +912,11 @@ public float getXHeight() {
return 0.5f;
}

@Override
public float getRootXHeight() {
return 0.5f;
}

/**
* Returns the viewport width used to compute units.
*/
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@
import java.awt.geom.Rectangle2D;
import java.lang.ref.SoftReference;

import org.w3c.css.om.unit.CSSUnit;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.events.DocumentEvent;
@@ -35,9 +36,12 @@
import io.sf.carte.echosvg.anim.dom.AnimatedLiveAttributeValue;
import io.sf.carte.echosvg.anim.dom.SVGOMAnimatedTransformList;
import io.sf.carte.echosvg.anim.dom.SVGOMElement;
import io.sf.carte.echosvg.css.CSSSecurityException;
import io.sf.carte.echosvg.css.engine.CSSEngine;
import io.sf.carte.echosvg.css.engine.CSSEngineEvent;
import io.sf.carte.echosvg.css.engine.SVGCSSEngine;
import io.sf.carte.echosvg.css.engine.value.LengthManager;
import io.sf.carte.echosvg.css.engine.value.Value;
import io.sf.carte.echosvg.dom.events.AbstractEvent;
import io.sf.carte.echosvg.dom.svg.AbstractSVGTransformList;
import io.sf.carte.echosvg.dom.svg.LiveAttributeException;
@@ -603,27 +607,59 @@ public float getViewportHeight() {
*/
@Override
public float getFontSize() {
return CSSUtilities.getComputedStyle(e, SVGCSSEngine.FONT_SIZE_INDEX).getFloatValue();
return fontSizeValue(e);
}

/**
* Returns the line-height on the associated element.
*/
@Override
public float getLineHeight() {
return CSSUtilities.getComputedStyle(e, SVGCSSEngine.LINE_HEIGHT_INDEX).getFloatValue();
return lineHeightValue(e);
}

@Override
public float getRootFontSize() {
Element root = e.getOwnerDocument().getDocumentElement();
return CSSUtilities.getComputedStyle(root, SVGCSSEngine.FONT_SIZE_INDEX).getFloatValue();
return fontSizeValue(root);
}

@Override
public float getRootLineHeight() {
Element root = e.getOwnerDocument().getDocumentElement();
return CSSUtilities.getComputedStyle(root, SVGCSSEngine.LINE_HEIGHT_INDEX).getFloatValue();
return lineHeightValue(root);
}

private float fontSizeValue(Element elt) {
try {
return CSSUtilities.getComputedStyle(elt, SVGCSSEngine.FONT_SIZE_INDEX).getFloatValue();
} catch (CSSSecurityException ex) {
}

if (ctx != null) {
return ctx.getUserAgent().getMediumFontSize();
}

return 12f;
}

private float lineHeightValue(Element elt) {
Value v;
try {
v = CSSUtilities.getComputedStyle(elt, SVGCSSEngine.LINE_HEIGHT_INDEX);
} catch (CSSSecurityException ex) {
return fontSizeValue(elt) * LengthManager.DEFAULT_LINE_HEIGHT;
}

float fv = v.getFloatValue();
short unit = v.getUnitType();
if (unit == CSSUnit.CSS_NUMBER) {
float fs = fontSizeValue(elt);
return fs * fv;
}

// Must be pixels
return fv;
}

}
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@
import io.sf.carte.doc.style.css.CSSValue.Type;
import io.sf.carte.echosvg.anim.dom.SVGOMDocument;
import io.sf.carte.echosvg.constants.XMLConstants;
import io.sf.carte.echosvg.css.CSSSecurityException;
import io.sf.carte.echosvg.css.engine.CSSEngine;
import io.sf.carte.echosvg.css.engine.CSSStylableElement;
import io.sf.carte.echosvg.css.engine.SVGCSSEngine;
@@ -78,7 +79,7 @@ public static CSSEngine getCSSEngine(Element e) {
/**
* Returns the computed style of the given property.
*/
public static Value getComputedStyle(Element e, int property) {
public static Value getComputedStyle(Element e, int property) throws CSSSecurityException {
CSSEngine engine = getCSSEngine(e);
if (engine == null)
return null;
Original file line number Diff line number Diff line change
@@ -348,6 +348,11 @@ public float getXHeight() {
return 0.5f;
}

@Override
public float getRootXHeight() {
return 0.5f;
}

/**
* Returns the viewport width used to compute units.
*/
Original file line number Diff line number Diff line change
@@ -56,7 +56,7 @@ public abstract class LengthManager extends AbstractValueManager {
* on a path". Web browsers use a default based on the font family, close to 1.2
* </p>
*/
protected static final float DEFAULT_LINE_HEIGHT = 1.1f;
public static final float DEFAULT_LINE_HEIGHT = 1.1f;

/**
* precomputed square-root of 2.0
Original file line number Diff line number Diff line change
@@ -99,6 +99,21 @@ public void percentage() throws ParseException {
setUnit(CSSUnit.CSS_PERCENTAGE);
}

@Override
public void rem() throws ParseException {
setUnit(CSSUnit.CSS_REM);
}

@Override
public void rex() throws ParseException {
setUnit(CSSUnit.CSS_REX);
}

@Override
public void rlh() throws ParseException {
setUnit(CSSUnit.CSS_RLH);
}

@Override
public void vh() throws ParseException {
setUnit(CSSUnit.CSS_VH);
Original file line number Diff line number Diff line change
@@ -114,6 +114,27 @@ public interface LengthHandler {
*/
void percentage() throws ParseException;

/**
* Invoked when 'rem' has been parsed.
*
* @exception ParseException if an error occurs while processing the length
*/
void rem() throws ParseException;

/**
* Invoked when 'rex' has been parsed.
*
* @exception ParseException if an error occurs while processing the length
*/
void rex() throws ParseException;

/**
* Invoked when 'rlh' has been parsed.
*
* @exception ParseException if an error occurs while processing the length
*/
void rlh() throws ParseException;

/**
* Invoked when 'vh' has been parsed.
*
Original file line number Diff line number Diff line change
@@ -450,6 +450,37 @@ protected void parseLength() throws ParseException, IOException {
lengthHandler.percentage();
current = reader.read();
break;
case 'r':
current = reader.read();
switch (current) {
case 'e':
current = reader.read();
switch (current) {
case 'm':
lengthHandler.rem();
current = reader.read();
break;
case 'x':
lengthHandler.rex();
current = reader.read();
break;
default:
reportUnexpectedCharacterError(current);
}
break;
case 'l':
current = reader.read();
if (current != 'h') {
reportCharacterExpectedError('h', current);
break;
}
lengthHandler.rlh();
current = reader.read();
break;
default:
reportUnexpectedCharacterError(current);
}
break;
case 'v':
current = reader.read();
switch (current) {
@@ -462,6 +493,7 @@ protected void parseLength() throws ParseException, IOException {
current = reader.read();
break;
case 'm':
current = reader.read();
switch (current) {
case 'i':
current = reader.read();
Original file line number Diff line number Diff line change
@@ -143,6 +143,12 @@ public static float cssToUserSpace(float v, short type, short d, Context ctx) {
return exsToPixels(v, d, ctx);
case CSSUnit.CSS_LH:
return lhToPixels(v, d, ctx);
case CSSUnit.CSS_REM:
return remToPixels(v, d, ctx);
case CSSUnit.CSS_REX:
return rexToPixels(v, d, ctx);
case CSSUnit.CSS_RLH:
return rlhToPixels(v, d, ctx);
case CSSUnit.CSS_VW:
return vwToPixels(v, d, ctx);
case CSSUnit.CSS_VH:
@@ -201,6 +207,12 @@ public static float userSpaceToCSS(float v, short type, short d, Context ctx) {
return pixelsToExs(v, d, ctx);
case CSSUnit.CSS_LH:
return pixelsToLh(v, d, ctx);
case CSSUnit.CSS_REM:
return pixelsToRem(v, d, ctx);
case CSSUnit.CSS_REX:
return pixelsToRex(v, d, ctx);
case CSSUnit.CSS_RLH:
return pixelsToRlh(v, d, ctx);
case CSSUnit.CSS_VW:
return pixelsToVw(v, d, ctx);
case CSSUnit.CSS_VH:
@@ -354,6 +366,30 @@ protected static float remToPixels(float v, short d, Context ctx) {
return v * ctx.getRootFontSize();
}

/**
* Converts user units to rex units.
*
* @param v the value to convert
* @param d HORIZONTAL_LENGTH, VERTICAL_LENGTH, or OTHER_LENGTH
* @param ctx the context
*/
protected static float pixelsToRex(float v, short d, Context ctx) {
float xh = ctx.getRootXHeight();
return v / xh / ctx.getRootFontSize();
}

/**
* Converts rex 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 rexToPixels(float v, short d, Context ctx) {
float xh = ctx.getRootXHeight();
return v * xh * ctx.getRootFontSize();
}

/**
* Converts user units to rlh units.
*
@@ -495,6 +531,11 @@ public interface Context {
*/
float getRootFontSize();

/**
* Returns the x-height value of the :root element.
*/
float getRootXHeight();

/**
* Returns the line-height value of the :root element.
*/
Original file line number Diff line number Diff line change
@@ -73,6 +73,20 @@ public void test() throws Exception {
testLengthParser("-0px", "0.0px");

testLengthParser("0000%", "0.0%");

testLengthParser("1rem", "1.0rem");

testLengthParser("02rex", "2.0rex");

testLengthParser("2rlh", "2.0rlh");

testLengthParser(".2vh", "0.2vh");

testLengthParser("2vw", "2.0vw");

testLengthParser("2.667vmin", "2.667vmin");

testLengthParser("2.3vmax", "2.3vmax");
}

private class TestHandler extends DefaultLengthHandler {
@@ -143,6 +157,21 @@ public void percentage() throws ParseException {
buffer.append("%");
}

@Override
public void rem() throws ParseException {
buffer.append("rem");
}

@Override
public void rex() throws ParseException {
buffer.append("rex");
}

@Override
public void rlh() throws ParseException {
buffer.append("rlh");
}

@Override
public void vh() throws ParseException {
buffer.append("vh");
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 2ad9989

Please sign in to comment.