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 e38d308c9..98b2fd52b 100644 --- a/openpdf/src/main/java/com/lowagie/text/html/Markup.java +++ b/openpdf/src/main/java/com/lowagie/text/html/Markup.java @@ -213,6 +213,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 diff --git a/openpdf/src/main/java/com/lowagie/text/html/simpleparser/FactoryProperties.java b/openpdf/src/main/java/com/lowagie/text/html/simpleparser/FactoryProperties.java index e697bd742..222d9b777 100755 --- a/openpdf/src/main/java/com/lowagie/text/html/simpleparser/FactoryProperties.java +++ b/openpdf/src/main/java/com/lowagie/text/html/simpleparser/FactoryProperties.java @@ -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 h) { String style = h.get("style"); if (style == null) @@ -331,16 +332,23 @@ public static void insertStyle(Map 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), @@ -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; } @@ -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); } diff --git a/openpdf/src/test/java/com/lowagie/text/html/FontSizeTest.java b/openpdf/src/test/java/com/lowagie/text/html/FontSizeTest.java deleted file mode 100644 index 5399d3133..000000000 --- a/openpdf/src/test/java/com/lowagie/text/html/FontSizeTest.java +++ /dev/null @@ -1,112 +0,0 @@ -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 org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.io.FileOutputStream; -import java.io.StringReader; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class FontSizeTest { - - @Test - public void testFontSize() throws Exception { - StringReader reader = new StringReader( - "Text" + - "Text 8.0pt" - + "Text 20px" - + "Text 1.5em" - + "Text 50%"); - StyleSheet styleSheet = new StyleSheet(); - Map interfaceProps = new HashMap<>(); - List elements = HTMLWorker.parseToList(reader, styleSheet, interfaceProps); - - Document document = new Document(); - PdfWriter instance = PdfWriter.getInstance(document, new FileOutputStream("target/Font Size.pdf")); - document.open(); - instance.getInfo().put(PdfName.CREATOR, new PdfString(Document.getVersion())); - for (Element e : elements) { - document.add(e); - } - document.close(); - Paragraph paragraph = (Paragraph) elements.get(0); - Chunk chunk1 = (Chunk) paragraph.get(0); - float defaultFontSize = chunk1.getFont().getSize(); - Chunk chunk2 = (Chunk) paragraph.get(1); - Assertions.assertEquals(8.0, chunk2.getFont().getSize()); - Chunk chunk3 = (Chunk) paragraph.get(2); - Assertions.assertEquals(20.0, chunk3.getFont().getSize()); - Chunk chunk4 = (Chunk) paragraph.get(3); - Assertions.assertEquals(1.5 * defaultFontSize, chunk4.getFont().getSize()); - Chunk chunk5 = (Chunk) paragraph.get(4); - Assertions.assertEquals(0.5 * defaultFontSize, chunk5.getFont().getSize()); - } - - @Test - public 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, 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()); - } -} diff --git a/openpdf/src/test/java/com/lowagie/text/html/StylesTest.java b/openpdf/src/test/java/com/lowagie/text/html/StylesTest.java new file mode 100644 index 000000000..a35722a8f --- /dev/null +++ b/openpdf/src/test/java/com/lowagie/text/html/StylesTest.java @@ -0,0 +1,127 @@ +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 org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +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; + +/** + * 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 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 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 htmlToPdf(String htmlFileName, String pdfFileName) throws IOException { + StyleSheet styleSheet = new StyleSheet(); + Map 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 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 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 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()); + } +} diff --git a/openpdf/src/test/resources/stylesTest/backgroundColor.html b/openpdf/src/test/resources/stylesTest/backgroundColor.html new file mode 100644 index 000000000..ab323c069 --- /dev/null +++ b/openpdf/src/test/resources/stylesTest/backgroundColor.html @@ -0,0 +1,12 @@ + + + + + + + Blue background
+ Blue background
+ Blue background
+ Blue background
+ + diff --git a/openpdf/src/test/resources/stylesTest/fontColor.html b/openpdf/src/test/resources/stylesTest/fontColor.html new file mode 100644 index 000000000..254633401 --- /dev/null +++ b/openpdf/src/test/resources/stylesTest/fontColor.html @@ -0,0 +1,10 @@ + + + + + + + Blue text
+ Blue text
+ + diff --git a/openpdf/src/test/resources/stylesTest/fontSize.html b/openpdf/src/test/resources/stylesTest/fontSize.html new file mode 100644 index 000000000..b74062940 --- /dev/null +++ b/openpdf/src/test/resources/stylesTest/fontSize.html @@ -0,0 +1,13 @@ + + + + + + +Text
+Text 8.0pt
+Text 20px
+Text 1.5em
+Text 50% + + diff --git a/openpdf/src/test/resources/stylesTest/fontSizeNamed.html b/openpdf/src/test/resources/stylesTest/fontSizeNamed.html new file mode 100644 index 000000000..b52f4ef5a --- /dev/null +++ b/openpdf/src/test/resources/stylesTest/fontSizeNamed.html @@ -0,0 +1,23 @@ + + + + + + + + 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
+
+ +