Skip to content

Commit 1a6d2c9

Browse files
committed
Fixes #459 - Implements the rem CSS unit.
With test proof.
1 parent 1d9ff98 commit 1a6d2c9

File tree

9 files changed

+74
-2
lines changed

9 files changed

+74
-2
lines changed

openhtmltopdf-core/src/main/java/com/openhtmltopdf/context/StyleReference.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import com.openhtmltopdf.css.sheet.PropertyDeclaration;
4040
import com.openhtmltopdf.css.sheet.Stylesheet;
4141
import com.openhtmltopdf.css.sheet.StylesheetInfo;
42+
import com.openhtmltopdf.css.style.CalculatedStyle;
4243
import com.openhtmltopdf.extend.NamespaceHandler;
4344
import com.openhtmltopdf.extend.UserAgentCallback;
4445
import com.openhtmltopdf.extend.UserInterface;
@@ -72,6 +73,17 @@ public StyleReference(UserAgentCallback userAgent) {
7273
_stylesheetFactory = new StylesheetFactoryImpl(userAgent);
7374
}
7475

76+
/**
77+
* Gets the style of the root element, should be html tag.
78+
*/
79+
public CalculatedStyle getRootElementStyle() {
80+
if (_context != null && _doc != null) {
81+
return _context.getStyle(_doc.getDocumentElement());
82+
} else {
83+
return null;
84+
}
85+
}
86+
7587
/**
7688
* Sets the documentContext attribute of the StyleReference object
7789
*

openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/constants/ValueConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ public static boolean isAbsoluteUnit(short type) {
151151
return false;
152152
// refer to values known to the DerivedValue instance (tobe)
153153
case CSSPrimitiveValue.CSS_EMS:
154+
case CSSPrimitiveValue.CSS_REMS:
154155
case CSSPrimitiveValue.CSS_EXS:
155156
// length
156157
case CSSPrimitiveValue.CSS_IN:

openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/CSSParser.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1383,6 +1383,7 @@ private List<PropertyValue> expr(boolean literal) throws IOException {
13831383
case Token.URI:
13841384
case Token.HASH:
13851385
case Token.FUNCTION:
1386+
case Token.DIMENSION:
13861387
PropertyValue term = term(literal);
13871388
if (operatorToken != null) {
13881389
term.setOperator(operatorToken);
@@ -1462,7 +1463,19 @@ private PropertyValue term(boolean literal) throws IOException {
14621463
case Token.TIME:
14631464
case Token.FREQ:
14641465
case Token.DIMENSION:
1465-
throw new CSSParseException("Unsupported CSS unit " + extractUnit(t), getCurrentLine());
1466+
String unitType = extractUnit(t);
1467+
1468+
if ("rem".equals(unitType)) {
1469+
result = new PropertyValue(
1470+
CSSPrimitiveValue.CSS_REMS,
1471+
sign*Float.parseFloat(extractNumber(t)),
1472+
sign(sign) + getTokenValue(t));
1473+
next();
1474+
skip_whitespace();
1475+
} else {
1476+
throw new CSSParseException("Unsupported CSS unit " + unitType, getCurrentLine());
1477+
}
1478+
break;
14661479
case Token.NUMBER:
14671480
result = new PropertyValue(
14681481
CSSPrimitiveValue.CSS_NUMBER,

openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/CSSPrimitiveValue.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ public interface CSSPrimitiveValue extends CSSValue {
2727
public static final short CSS_COUNTER = 23;
2828
public static final short CSS_RECT = 24;
2929
public static final short CSS_RGBCOLOR = 25;
30-
30+
31+
/** rems unit, not official, added by danfickle. */
32+
public static final short CSS_REMS = 26;
33+
3134
public short getPrimitiveType();
3235
public float getFloatValue(short unitType);
3336
public String getStringValue();

openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/parser/property/AbstractPropertyBuilder.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ public static boolean isLengthHelper(CSSPrimitiveValue value) {
173173
|| unit == CSSPrimitiveValue.CSS_PX || unit == CSSPrimitiveValue.CSS_IN
174174
|| unit == CSSPrimitiveValue.CSS_CM || unit == CSSPrimitiveValue.CSS_MM
175175
|| unit == CSSPrimitiveValue.CSS_PT || unit == CSSPrimitiveValue.CSS_PC
176+
|| unit == CSSPrimitiveValue.CSS_REMS
176177
|| (unit == CSSPrimitiveValue.CSS_NUMBER && value.getFloatValue(CSSPrimitiveValue.CSS_IN) == 0.0f);
177178
}
178179

openhtmltopdf-core/src/main/java/com/openhtmltopdf/css/style/derived/LengthValue.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,19 @@ public static float calcFloatProportionalValue(CalculatedStyle style,
144144
}
145145

146146
break;
147+
case CSSPrimitiveValue.CSS_REMS: {
148+
// The rem unit is the same as em except uses the font-size of the html element
149+
// rather than the font-size of current/parent element.
150+
CalculatedStyle htmlTagStyle = ctx.getCss().getRootElementStyle();
151+
if (htmlTagStyle == null) {
152+
// The default font-size for the html tag is 16px.
153+
absVal = relVal * 16f * ctx.getDotsPerPixel();
154+
} else {
155+
FontSpecification htmlTagFontSpecification = htmlTagStyle.getFont(ctx);
156+
absVal = relVal * htmlTagFontSpecification.size;
157+
}
158+
break;
159+
}
147160
case CSSPrimitiveValue.CSS_EXS:
148161
// To convert EMS to pixels, we need the height of the lowercase 'Xx' character in the current
149162
// element...
Binary file not shown.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<html>
2+
<head>
3+
<style>
4+
@page {
5+
size: 15rem 240px;
6+
margin: 0.5rem;
7+
}
8+
body {
9+
border: 1px solid orange;
10+
margin: 1rem;
11+
max-width: 12rem;
12+
}
13+
</style>
14+
</head>
15+
<body>
16+
<!-- Should look the same if rem default amount is 16px -->
17+
<div style="margin: 16px; padding: 0.1rem 32px; border: 1.6px solid red; background-color: blue; height: 24px;">ONE</div>
18+
<div style="margin: 1rem; padding: 1.6px 2rem; border: 0.1rem solid red; background-color: blue; height: 1.5rem;">TWO</div>
19+
</body>
20+
</html>

openhtmltopdf-examples/src/test/java/com/openhtmltopdf/visualregressiontests/VisualRegressionTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,15 @@ public void testIssue446LangSelector() throws IOException {
10071007
assertTrue(vt.runTest("issue-446-lang-selector"));
10081008
}
10091009

1010+
/**
1011+
* Tests that the rem unit work with a document that has no author
1012+
* font-size set on the html element (defaults to 16px).
1013+
*/
1014+
@Test
1015+
public void testIssue459RemUnitDefault() throws IOException {
1016+
assertTrue(vt.runTest("issue-459-rem-unit-default"));
1017+
}
1018+
10101019
/**
10111020
* Tests what the CSS content property is capable of.
10121021
*/

0 commit comments

Comments
 (0)