diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/context/StyleReference.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/context/StyleReference.java
index 563b3005a..fe2bcfac7 100644
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/context/StyleReference.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/context/StyleReference.java
@@ -39,6 +39,7 @@
import com.openhtmltopdf.css.sheet.PropertyDeclaration;
import com.openhtmltopdf.css.sheet.Stylesheet;
import com.openhtmltopdf.css.sheet.StylesheetInfo;
+import com.openhtmltopdf.css.style.CalculatedStyle;
import com.openhtmltopdf.extend.NamespaceHandler;
import com.openhtmltopdf.extend.UserAgentCallback;
import com.openhtmltopdf.extend.UserInterface;
@@ -72,6 +73,17 @@ public StyleReference(UserAgentCallback userAgent) {
_stylesheetFactory = new StylesheetFactoryImpl(userAgent);
}
+ /**
+ * Gets the style of the root element, should be html tag.
+ */
+ public CalculatedStyle getRootElementStyle() {
+ if (_context != null && _doc != null) {
+ return _context.getStyle(_doc.getDocumentElement());
+ } else {
+ return null;
+ }
+ }
+
/**
* Sets the documentContext attribute of the StyleReference object
*
diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/constants/ValueConstants.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/constants/ValueConstants.java
index 51f49cdae..e363455f0 100644
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/constants/ValueConstants.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/constants/ValueConstants.java
@@ -151,6 +151,7 @@ public static boolean isAbsoluteUnit(short type) {
return false;
// refer to values known to the DerivedValue instance (tobe)
case CSSPrimitiveValue.CSS_EMS:
+ case CSSPrimitiveValue.CSS_REMS:
case CSSPrimitiveValue.CSS_EXS:
// length
case CSSPrimitiveValue.CSS_IN:
diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/CSSParser.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/CSSParser.java
index 5424de5f0..d90d147f7 100644
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/CSSParser.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/CSSParser.java
@@ -1383,6 +1383,7 @@ private List expr(boolean literal) throws IOException {
case Token.URI:
case Token.HASH:
case Token.FUNCTION:
+ case Token.DIMENSION:
PropertyValue term = term(literal);
if (operatorToken != null) {
term.setOperator(operatorToken);
@@ -1462,7 +1463,19 @@ private PropertyValue term(boolean literal) throws IOException {
case Token.TIME:
case Token.FREQ:
case Token.DIMENSION:
- throw new CSSParseException("Unsupported CSS unit " + extractUnit(t), getCurrentLine());
+ String unitType = extractUnit(t);
+
+ if ("rem".equals(unitType)) {
+ result = new PropertyValue(
+ CSSPrimitiveValue.CSS_REMS,
+ sign*Float.parseFloat(extractNumber(t)),
+ sign(sign) + getTokenValue(t));
+ next();
+ skip_whitespace();
+ } else {
+ throw new CSSParseException("Unsupported CSS unit " + unitType, getCurrentLine());
+ }
+ break;
case Token.NUMBER:
result = new PropertyValue(
CSSPrimitiveValue.CSS_NUMBER,
diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/CSSPrimitiveValue.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/CSSPrimitiveValue.java
index 990f4939e..e73bdf4db 100644
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/CSSPrimitiveValue.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/CSSPrimitiveValue.java
@@ -27,7 +27,10 @@ public interface CSSPrimitiveValue extends CSSValue {
public static final short CSS_COUNTER = 23;
public static final short CSS_RECT = 24;
public static final short CSS_RGBCOLOR = 25;
-
+
+ /** rems unit, not official, added by danfickle. */
+ public static final short CSS_REMS = 26;
+
public short getPrimitiveType();
public float getFloatValue(short unitType);
public String getStringValue();
diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/property/AbstractPropertyBuilder.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/property/AbstractPropertyBuilder.java
index 108b42f35..ccd20397d 100644
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/property/AbstractPropertyBuilder.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/property/AbstractPropertyBuilder.java
@@ -173,6 +173,7 @@ public static boolean isLengthHelper(CSSPrimitiveValue value) {
|| unit == CSSPrimitiveValue.CSS_PX || unit == CSSPrimitiveValue.CSS_IN
|| unit == CSSPrimitiveValue.CSS_CM || unit == CSSPrimitiveValue.CSS_MM
|| unit == CSSPrimitiveValue.CSS_PT || unit == CSSPrimitiveValue.CSS_PC
+ || unit == CSSPrimitiveValue.CSS_REMS
|| (unit == CSSPrimitiveValue.CSS_NUMBER && value.getFloatValue(CSSPrimitiveValue.CSS_IN) == 0.0f);
}
diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/derived/LengthValue.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/derived/LengthValue.java
index 785bf6d9f..9ad16e622 100644
--- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/derived/LengthValue.java
+++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/derived/LengthValue.java
@@ -144,6 +144,19 @@ public static float calcFloatProportionalValue(CalculatedStyle style,
}
break;
+ case CSSPrimitiveValue.CSS_REMS: {
+ // The rem unit is the same as em except uses the font-size of the html element
+ // rather than the font-size of current/parent element.
+ CalculatedStyle htmlTagStyle = ctx.getCss().getRootElementStyle();
+ if (htmlTagStyle == null) {
+ // The default font-size for the html tag is 16px.
+ absVal = relVal * 16f * ctx.getDotsPerPixel();
+ } else {
+ FontSpecification htmlTagFontSpecification = htmlTagStyle.getFont(ctx);
+ absVal = relVal * htmlTagFontSpecification.size;
+ }
+ break;
+ }
case CSSPrimitiveValue.CSS_EXS:
// To convert EMS to pixels, we need the height of the lowercase 'Xx' character in the current
// element...
diff --git a/openhtmltopdf-examples/src/main/resources/visualtest/expected/issue-459-rem-unit-default.pdf b/openhtmltopdf-examples/src/main/resources/visualtest/expected/issue-459-rem-unit-default.pdf
new file mode 100644
index 000000000..3279fb052
Binary files /dev/null and b/openhtmltopdf-examples/src/main/resources/visualtest/expected/issue-459-rem-unit-default.pdf differ
diff --git a/openhtmltopdf-examples/src/main/resources/visualtest/html/issue-459-rem-unit-default.html b/openhtmltopdf-examples/src/main/resources/visualtest/html/issue-459-rem-unit-default.html
new file mode 100644
index 000000000..8927e51a1
--- /dev/null
+++ b/openhtmltopdf-examples/src/main/resources/visualtest/html/issue-459-rem-unit-default.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+ ONE
+ TWO
+
+
diff --git a/openhtmltopdf-examples/src/test/java/com/openhtmltopdf/visualregressiontests/VisualRegressionTest.java b/openhtmltopdf-examples/src/test/java/com/openhtmltopdf/visualregressiontests/VisualRegressionTest.java
index 8e55da7fb..28b639706 100644
--- a/openhtmltopdf-examples/src/test/java/com/openhtmltopdf/visualregressiontests/VisualRegressionTest.java
+++ b/openhtmltopdf-examples/src/test/java/com/openhtmltopdf/visualregressiontests/VisualRegressionTest.java
@@ -1007,6 +1007,15 @@ public void testIssue446LangSelector() throws IOException {
assertTrue(vt.runTest("issue-446-lang-selector"));
}
+ /**
+ * Tests that the rem unit work with a document that has no author
+ * font-size set on the html element (defaults to 16px).
+ */
+ @Test
+ public void testIssue459RemUnitDefault() throws IOException {
+ assertTrue(vt.runTest("issue-459-rem-unit-default"));
+ }
+
/**
* Tests what the CSS content property is capable of.
*/