Skip to content

Commit

Permalink
#1057 CSS font-size property fails with IllegalArgumentException (#1072)
Browse files Browse the repository at this point in the history
* #1057 Generating PDF from HTML containing CSS font-size property fails with IllegalArgumentException

---------

Co-authored-by: Radek Wikturna <radek.wikturna@usu.com>
  • Loading branch information
2 people authored and asturio committed Feb 23, 2024
1 parent 2e5a437 commit 33dd6eb
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 0 deletions.
57 changes: 57 additions & 0 deletions openpdf/src/main/java/com/lowagie/text/html/FontSize.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.lowagie.text.html;

/**
* Named font sizes defined by CSS
* <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/font-size">font-size</a> 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;
}
}
9 changes: 9 additions & 0 deletions openpdf/src/main/java/com/lowagie/text/html/Markup.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
59 changes: 59 additions & 0 deletions openpdf/src/test/java/com/lowagie/text/html/FontSizeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(
"<span style=\"font-size:20pt\">" +
"<span style=\"font-size:xx-small\">Text xx-small</span><br/>" +
"<span style=\"font-size:x-small\">Text x-small</span><br/>" +
"<span style=\"font-size:small\">Text small</span><br/>" +
"<span style=\"font-size:medium\">Text medium</span><br/>" +
"<span style=\"font-size:large\">Text large</span><br/>" +
"<span style=\"font-size:x-large\">Text x-large</span><br/>" +
"<span style=\"font-size:xx-large\">Text xx-large</span><br/>" +
"<span style=\"font-size:xxx-large\">Text xxx-large</span><br/>" +
"</span>" +

"<span style=\"font-size:20pt\">" +
"<span style=\"font-size:smaller\">Text smaller</span><br/>" +
"<span style=\"font-size:larger\">Text larger</span><br/>" +
"</span>"
);
StyleSheet styleSheet = new StyleSheet();
Map<String, Object> interfaceProps = new HashMap<>();
List<Element> 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());
}
}

0 comments on commit 33dd6eb

Please sign in to comment.