Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#1057 Generating PDF from HTML containing CSS font-size property fails with IllegalArgumentException #1072

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 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,55 @@
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.length() == 0 || !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 @@ -352,6 +352,15 @@ public static float parseLength(String string) {
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
57 changes: 57 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 @@ -52,4 +52,61 @@ public void testFontSize() throws Exception {
Chunk chunk5 = (Chunk) paragraph.get(4);
Assertions.assertEquals(0.5 * defaultFontSize, chunk5.getFont().getSize());
}

@Test
public 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, new FileOutputStream("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());
}
}