diff --git a/openpdf/src/main/java/com/lowagie/text/html/FontSize.java b/openpdf/src/main/java/com/lowagie/text/html/FontSize.java
new file mode 100644
index 000000000..b6ddad93b
--- /dev/null
+++ b/openpdf/src/main/java/com/lowagie/text/html/FontSize.java
@@ -0,0 +1,57 @@
+package com.lowagie.text.html;
+
+/**
+ * Named font sizes defined by CSS
+ * font-size property
+ */
+public enum FontSize {
+
+ // Absolute-size keywords, based on the user's default font size (which is medium).
+ XX_SMALL("xx-small", 0.6f, false),
+ X_SMALL("x-small", 0.75f, false),
+ SMALL("small", 0.89f, false),
+ MEDIUM("medium", 1.0f, false),
+ LARGE("large", 1.2f, false),
+ X_LARGE("x-large", 1.5f, false),
+ XX_LARGE("xx-large", 2.0f, false),
+ XXX_LARGE("xxx-large", 2.5f, false),
+
+ // Relative-size keywords. The font will be larger or smaller relative to the parent element's font size,
+ // roughly by the ratio used to separate the absolute-size keywords above.
+ SMALLER("smaller", 0.89f, true),
+ LARGER("larger", 1.2f, true);
+
+ private final float scale;
+ private final String textValue;
+ private final boolean relative;
+
+ FontSize(String textValue, float scale, boolean relative) {
+ this.textValue = textValue;
+ this.scale = scale;
+ this.relative = relative;
+ }
+
+ public String getTextValue() {
+ return textValue;
+ }
+
+ public float getScale() {
+ return scale;
+ }
+
+ public boolean isRelative() {
+ return relative;
+ }
+
+ public static FontSize parse(String text) {
+ if (text == null || text.isEmpty() || !Character.isLetter(text.charAt(0))) {
+ return null;
+ }
+ for (FontSize fontSize : values()) {
+ if (fontSize.getTextValue().equalsIgnoreCase(text)) {
+ return fontSize;
+ }
+ }
+ return null;
+ }
+}
diff --git a/openpdf/src/main/java/com/lowagie/text/html/Markup.java b/openpdf/src/main/java/com/lowagie/text/html/Markup.java
index c36f3187e..5c2b4a82a 100644
--- a/openpdf/src/main/java/com/lowagie/text/html/Markup.java
+++ b/openpdf/src/main/java/com/lowagie/text/html/Markup.java
@@ -479,6 +479,15 @@ public static float parseLength(String string, float actualFontSize) {
if (string == null) {
return 0f;
}
+ FontSize fs = FontSize.parse(string);// it can be one of the CCS font size names (e.g. 'x-large')
+ if (fs != null) {
+ if (fs.isRelative()) {
+ return fs.getScale() * actualFontSize;
+ } else {
+ return fs.getScale() * DEFAULT_FONT_SIZE;
+ }
+ }
+
int pos = 0;
int length = string.length();
boolean ok = true;
diff --git a/openpdf/src/test/java/com/lowagie/text/html/FontSizeTest.java b/openpdf/src/test/java/com/lowagie/text/html/FontSizeTest.java
index 86d3f151a..e645bfc06 100644
--- a/openpdf/src/test/java/com/lowagie/text/html/FontSizeTest.java
+++ b/openpdf/src/test/java/com/lowagie/text/html/FontSizeTest.java
@@ -11,6 +11,7 @@
import com.lowagie.text.pdf.PdfWriter;
import java.io.StringReader;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
@@ -52,4 +53,62 @@ void testFontSize() throws Exception {
Chunk chunk5 = (Chunk) paragraph.get(4);
Assertions.assertEquals(0.5 * defaultFontSize, chunk5.getFont().getSize());
}
+
+ @Test
+ void testNamedFontSize() throws Exception {
+ StringReader reader = new StringReader(
+ "" +
+ "Text xx-small
" +
+ "Text x-small
" +
+ "Text small
" +
+ "Text medium
" +
+ "Text large
" +
+ "Text x-large
" +
+ "Text xx-large
" +
+ "Text xxx-large
" +
+ "" +
+
+ "" +
+ "Text smaller
" +
+ "Text larger
" +
+ ""
+ );
+ StyleSheet styleSheet = new StyleSheet();
+ Map interfaceProps = new HashMap<>();
+ List elements = HTMLWorker.parseToList(reader, styleSheet, interfaceProps);
+
+ Document document = new Document();
+ PdfWriter instance = PdfWriter.getInstance(document,
+ Files.newOutputStream(Path.of("target/Font Size Named.pdf")));
+ document.open();
+ instance.getInfo().put(PdfName.CREATOR, new PdfString(Document.getVersion()));
+ for (Element e : elements) {
+ document.add(e);
+ }
+ document.close();
+
+ int i = 0;
+ Paragraph paragraph = (Paragraph) elements.get(0);
+ Chunk chunk1 = (Chunk) paragraph.get((i++) * 2);
+ Assertions.assertEquals(FontSize.XX_SMALL.getScale() * Markup.DEFAULT_FONT_SIZE, chunk1.getFont().getSize());
+ Chunk chunk2 = (Chunk) paragraph.get((i++) * 2);
+ Assertions.assertEquals(FontSize.X_SMALL.getScale() * Markup.DEFAULT_FONT_SIZE, chunk2.getFont().getSize());
+ Chunk chunk3 = (Chunk) paragraph.get((i++) * 2);
+ Assertions.assertEquals(FontSize.SMALL.getScale() * Markup.DEFAULT_FONT_SIZE, chunk3.getFont().getSize());
+ Chunk chunk4 = (Chunk) paragraph.get((i++) * 2);
+ Assertions.assertEquals(FontSize.MEDIUM.getScale() * Markup.DEFAULT_FONT_SIZE, chunk4.getFont().getSize());
+ Chunk chunk5 = (Chunk) paragraph.get((i++) * 2);
+ Assertions.assertEquals(FontSize.LARGE.getScale() * Markup.DEFAULT_FONT_SIZE, chunk5.getFont().getSize());
+ Chunk chunk6 = (Chunk) paragraph.get((i++) * 2);
+ Assertions.assertEquals(FontSize.X_LARGE.getScale() * Markup.DEFAULT_FONT_SIZE, chunk6.getFont().getSize());
+ Chunk chunk7 = (Chunk) paragraph.get((i++) * 2);
+ Assertions.assertEquals(FontSize.XX_LARGE.getScale() * Markup.DEFAULT_FONT_SIZE, chunk7.getFont().getSize());
+ Chunk chunk8 = (Chunk) paragraph.get((i++) * 2);
+ Assertions.assertEquals(FontSize.XXX_LARGE.getScale() * Markup.DEFAULT_FONT_SIZE, chunk8.getFont().getSize());
+
+ Chunk chunk9 = (Chunk) paragraph.get((i++) * 2);
+ Assertions.assertEquals(FontSize.SMALLER.getScale() * 20f, chunk9.getFont().getSize());
+ Chunk chunk10 = (Chunk) paragraph.get((i++) * 2);
+ Assertions.assertEquals(FontSize.LARGER.getScale() * 20f, chunk10.getFont().getSize());
+ }
}