Skip to content

Commit

Permalink
#1061 When converting HTML to PDF, background color is not applied (#…
Browse files Browse the repository at this point in the history
…1075)

* #1061 When converting HTML to PDF, background color is not applied

---------

Co-authored-by: Radek Wikturna <[email protected]>
  • Loading branch information
2 people authored and asturio committed Feb 23, 2024
1 parent bcb0e01 commit 340661b
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 123 deletions.
3 changes: 3 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 @@ -305,6 +305,9 @@ public class Markup {

// CSS values

/** the CSS tag for background style */
public static final String CSS_KEY_BG = "background";

/**
* value for the CSS tag for adding a page break when the document is printed
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ public static HyphenationEvent getHyphenation(String s) {
return new HyphenationAuto(lang, country, leftMin, rightMin);
}

@Deprecated // this method is nor called anywhere. But it is public so theoretically it could be called by consumers of OpenPdf, but why?
public static void insertStyle(Map<String, String> h) {
String style = h.get("style");
if (style == null)
Expand Down Expand Up @@ -331,16 +332,23 @@ public static void insertStyle(Map<String, String> h, ChainedProperties cprops)
h.put("u", null);
break;
}
case Markup.CSS_KEY_COLOR:
Color c = Markup.decodeColor(prop.getProperty(key));
if (c != null) {
int hh = c.getRGB();
String hs = Integer.toHexString(hh);
hs = "000000" + hs;
hs = "#" + hs.substring(hs.length() - 6);
h.put("color", hs);
case Markup.CSS_KEY_BGCOLOR: {
h.put(Markup.CSS_KEY_BGCOLOR, prop.getProperty(key));
break;
}
case Markup.CSS_KEY_BG: {
for(String attribute: prop.getProperty(key).split(" ")) {
Color c = Markup.decodeColor(attribute.trim());
if (c != null) {
h.put(Markup.CSS_KEY_BGCOLOR, attribute.trim());
break;
}
}
break;
}
case Markup.CSS_KEY_COLOR:
h.put(Markup.CSS_KEY_COLOR, prop.getProperty(key));
break;
case Markup.CSS_KEY_LINEHEIGHT: {
String ss = prop.getProperty(key).trim();
float actualFontSize = parseLength(cprops.getProperty(ElementTags.SIZE),
Expand Down Expand Up @@ -388,6 +396,10 @@ public Chunk createChunk(String text, ChainedProperties props) {
} else if (props.hasProperty("sup")) {
chunk.setTextRise(size);
}
Color bgColor = Markup.decodeColor(props.getProperty(Markup.CSS_KEY_BGCOLOR));
if (bgColor != null) {
chunk.setBackground(bgColor);
}
chunk.setHyphenation(getHyphenation(props));
return chunk;
}
Expand Down Expand Up @@ -420,7 +432,7 @@ public Font getFont(ChainedProperties props) {
.flatMap(NumberUtilities::parseFloat)
.orElse(12f);

Color color = Markup.decodeColor(props.getProperty("color"));
Color color = Markup.decodeColor(props.getProperty(Markup.CSS_KEY_COLOR));
String encoding = props.getOrDefault("encoding", BaseFont.WINANSI);
return fontImp.getFont(face, encoding, true, size, style, color);
}
Expand Down
114 changes: 0 additions & 114 deletions openpdf/src/test/java/com/lowagie/text/html/FontSizeTest.java

This file was deleted.

126 changes: 126 additions & 0 deletions openpdf/src/test/java/com/lowagie/text/html/StylesTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package com.lowagie.text.html;

import com.lowagie.text.Chunk;
import com.lowagie.text.Document;
import com.lowagie.text.Element;
import com.lowagie.text.Paragraph;
import com.lowagie.text.html.simpleparser.HTMLWorker;
import com.lowagie.text.html.simpleparser.StyleSheet;
import com.lowagie.text.pdf.PdfName;
import com.lowagie.text.pdf.PdfString;
import com.lowagie.text.pdf.PdfWriter;
import java.awt.Color;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

/**
* Tests generating PDF from HTML with selected CCS style attributes (such as 'font-size', 'background', 'background-color', 'color').
*/
class StylesTest {

@Test
void testBackgroundColor() throws Exception {
List<Element> elements = htmlToPdf("stylesTest/backgroundColor.html", "target/Background Color.pdf");
Paragraph paragraph = (Paragraph) elements.get(0);
Chunk chunk1 = (Chunk) paragraph.get(0);
Assertions.assertEquals(Color.BLUE, getBackgroundColor(chunk1));
Chunk chunk2 = (Chunk) paragraph.get(2);
Assertions.assertEquals(Color.BLUE, getBackgroundColor(chunk2));
Chunk chunk3 = (Chunk) paragraph.get(4);
Assertions.assertEquals(Color.BLUE, getBackgroundColor(chunk3));
Chunk chunk4 = (Chunk) paragraph.get(6);
Assertions.assertEquals(Color.BLUE, getBackgroundColor(chunk4));
}

private Color getBackgroundColor(Chunk chunk) {
Object[] backgroundAttributes = (Object[]) chunk.getChunkAttributes().get(Chunk.BACKGROUND);
if (backgroundAttributes != null && backgroundAttributes.length > 0 && backgroundAttributes[0] instanceof Color ) {
return (Color)backgroundAttributes[0];
}
return null;
}

@Test
void testFontColor() throws Exception {
List<Element> elements = htmlToPdf("stylesTest/fontColor.html", "target/Font Color.pdf");
Paragraph paragraph = (Paragraph) elements.get(0);
Chunk chunk1 = (Chunk) paragraph.get(0);
Assertions.assertEquals(Color.BLUE, chunk1.getFont().getColor());
Chunk chunk2 = (Chunk) paragraph.get(2);
Assertions.assertEquals(Color.BLUE, chunk2.getFont().getColor());
}

private List<Element> htmlToPdf(String htmlFileName, String pdfFileName) throws IOException {
StyleSheet styleSheet = new StyleSheet();
Map<String, Object> interfaceProps = new HashMap<>();
try(InputStream inputStream = StylesTest.class.getClassLoader().getResourceAsStream(htmlFileName);
OutputStream outputStream = Files.newOutputStream(Paths.get(pdfFileName))) {
if (inputStream == null) {
throw new IOException("InputStream could not be created");
}
List<Element> elements = HTMLWorker.parseToList(new InputStreamReader(inputStream), styleSheet, interfaceProps);

Document document = new Document();
PdfWriter instance = PdfWriter.getInstance(document, outputStream);
document.open();
instance.getInfo().put(PdfName.CREATOR, new PdfString(Document.getVersion()));
for (Element e : elements) {
document.add(e);
}
document.close();
return elements;
}
}

@Test
void testFontSize() throws Exception {
List<Element> elements = htmlToPdf("stylesTest/fontSize.html", "target/Font Size.pdf");
Paragraph paragraph = (Paragraph) elements.get(0);
Chunk chunk1 = (Chunk) paragraph.get(0);
float defaultFontSize = chunk1.getFont().getSize();
Chunk chunk2 = (Chunk) paragraph.get(2);
Assertions.assertEquals(8.0, chunk2.getFont().getSize());
Chunk chunk3 = (Chunk) paragraph.get(4);
Assertions.assertEquals(20.0, chunk3.getFont().getSize());
Chunk chunk4 = (Chunk) paragraph.get(6);
Assertions.assertEquals(1.5 * defaultFontSize, chunk4.getFont().getSize());
Chunk chunk5 = (Chunk) paragraph.get(8);
Assertions.assertEquals(0.5 * defaultFontSize, chunk5.getFont().getSize());
}

@Test
void testNamedFontSize() throws Exception {
List<Element> elements = htmlToPdf("stylesTest/fontSizeNamed.html", "target/Font Size Named.pdf");
Paragraph paragraph = (Paragraph) elements.get(0);
Chunk chunk1 = (Chunk) paragraph.get(0);
Assertions.assertEquals(FontSize.XX_SMALL.getScale() * Markup.DEFAULT_FONT_SIZE, chunk1.getFont().getSize());
Chunk chunk2 = (Chunk) paragraph.get(2);
Assertions.assertEquals(FontSize.X_SMALL.getScale() * Markup.DEFAULT_FONT_SIZE, chunk2.getFont().getSize());
Chunk chunk3 = (Chunk) paragraph.get(4);
Assertions.assertEquals(FontSize.SMALL.getScale() * Markup.DEFAULT_FONT_SIZE, chunk3.getFont().getSize());
Chunk chunk4 = (Chunk) paragraph.get(6);
Assertions.assertEquals(FontSize.MEDIUM.getScale() * Markup.DEFAULT_FONT_SIZE, chunk4.getFont().getSize());
Chunk chunk5 = (Chunk) paragraph.get(8);
Assertions.assertEquals(FontSize.LARGE.getScale() * Markup.DEFAULT_FONT_SIZE, chunk5.getFont().getSize());
Chunk chunk6 = (Chunk) paragraph.get(10);
Assertions.assertEquals(FontSize.X_LARGE.getScale() * Markup.DEFAULT_FONT_SIZE, chunk6.getFont().getSize());
Chunk chunk7 = (Chunk) paragraph.get(12);
Assertions.assertEquals(FontSize.XX_LARGE.getScale() * Markup.DEFAULT_FONT_SIZE, chunk7.getFont().getSize());
Chunk chunk8 = (Chunk) paragraph.get(14);
Assertions.assertEquals(FontSize.XXX_LARGE.getScale() * Markup.DEFAULT_FONT_SIZE, chunk8.getFont().getSize());

Chunk chunk9 = (Chunk) paragraph.get(16);
Assertions.assertEquals(FontSize.SMALLER.getScale() * 20f, chunk9.getFont().getSize());
Chunk chunk10 = (Chunk) paragraph.get(18);
Assertions.assertEquals(FontSize.LARGER.getScale() * 20f, chunk10.getFont().getSize());
}
}
12 changes: 12 additions & 0 deletions openpdf/src/test/resources/stylesTest/backgroundColor.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<span style="background-color:#0000ff">Blue background</span><br/>
<span style="background-color:blue">Blue background</span><br/>
<span style="background: none repeat scroll 0% 0% #0000ff">Blue background</span><br/>
<span style="background: blue none repeat scroll 0% 0%">Blue background</span><br/>
</body>
</html>
10 changes: 10 additions & 0 deletions openpdf/src/test/resources/stylesTest/fontColor.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<span style="color:#0000ff">Blue text</span><br/>
<span style="color:blue">Blue text</span><br/>
</body>
</html>
13 changes: 13 additions & 0 deletions openpdf/src/test/resources/stylesTest/fontSize.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<span>Text</span><br/>
<span style="font-size:8.0pt">Text 8.0pt</span><br/>
<span style="font-size:20px">Text 20px</span><br/>
<span style="font-size:1.5em">Text 1.5em</span><br/>
<span style="font-size:50%">Text 50%</span>
</body>
</html>
23 changes: 23 additions & 0 deletions openpdf/src/test/resources/stylesTest/fontSizeNamed.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<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>
</body>
</html>

0 comments on commit 340661b

Please sign in to comment.