Skip to content
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
72 changes: 43 additions & 29 deletions java/src/main/java/com/genexus/reports/PDFReportItext8.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
import com.genexus.webpanels.HttpContextWeb;

import com.itextpdf.barcodes.Barcode128;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.io.font.constants.StandardFonts;
import com.itextpdf.io.font.otf.Glyph;
Expand All @@ -33,6 +35,8 @@
import com.itextpdf.layout.borders.Border;
import com.itextpdf.layout.element.*;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.layout.LayoutArea;
import com.itextpdf.layout.layout.LayoutContext;
import com.itextpdf.layout.properties.*;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.layout.splitting.DefaultSplitCharacters;
Expand Down Expand Up @@ -79,7 +83,7 @@ protected void init() {
pdfDocument = new PdfDocument(writer);
pdfDocument.setDefaultPageSize(this.pageSize);
document = new Document(pdfDocument);

document.setFontProvider(new DefaultFontProvider());
} catch (Exception e){
log.error("Failed to initialize new iText7 document: ", e);
}
Expand Down Expand Up @@ -525,6 +529,7 @@ else if (fontBold)
else
baseFont = PdfFontFactory.createFont(fontPath, PdfEncodings.IDENTITY_H, EmbeddingStrategy.PREFER_EMBEDDED);
}
document.getFontProvider().addFont(baseFont.getFontProgram());
}
catch(IOException ioe) {
log.error("GxAttris failed: ", ioe);
Expand Down Expand Up @@ -586,8 +591,7 @@ else if (valign == VerticalAlign.BOTTOM.value())
boolean autoResize = (align & 256) == 256;

if (htmlformat == 1) {
//As of now, you might experience unexpected behaviour since not all possible
//HTML code is supported
log.info("As of now, you might experience unexpected behaviour since not all possible HTML code is supported");
try {
bottomAux = (float)convertScale(bottom);
topAux = (float)convertScale(top);
Expand All @@ -604,10 +608,12 @@ else if (valign == VerticalAlign.BOTTOM.value())
YPosition yPosition = new YPosition(htmlRectangle.getTop());
TextAlignment txtAlignment = getTextAlignment(alignment);

ConverterProperties converterProperties = new ConverterProperties();
converterProperties.setFontProvider(document.getFontProvider());
//Iterate over the elements (a.k.a the parsed HTML string) and handle each case accordingly
List<IElement> elements = HtmlConverter.convertToElements(sTxt);
List<IElement> elements = HtmlConverter.convertToElements(sTxt, converterProperties);
for (IElement element : elements)
processHTMLElement(canvas,htmlRectangle, yPosition, txtAlignment, (IBlockElement) element);
processHTMLElement(htmlRectangle, yPosition, txtAlignment, (IBlockElement) element);
} catch (Exception e) {
log.error("GxDrawText failed to print HTML text : ", e);
}
Expand Down Expand Up @@ -734,39 +740,47 @@ else if (valign == VerticalAlign.BOTTOM.value())
}
}

void processHTMLElement(Canvas canvas, Rectangle htmlRectangle, YPosition currentYPosition, TextAlignment txtAlignment, IBlockElement blockElement){
float padding = 5f;
void processHTMLElement(Rectangle htmlRectangle, YPosition currentYPosition, TextAlignment txtAlignment, IBlockElement blockElement){
if (blockElement instanceof Paragraph){
Paragraph p = (Paragraph) blockElement;

// calculate the height of the Paragraph
float marginTop = (p.getMarginTop() != null) ? p.getMarginTop().getValue() : 0;
float marginBottom = (p.getMarginBottom() != null) ? p.getMarginBottom().getValue() : 0;
float paddingTop = (p.getPaddingTop() != null) ? p.getPaddingTop().getValue() : 0;
float paddingBottom = (p.getPaddingBottom() != null) ? p.getPaddingBottom().getValue() : 0;
float height = marginTop + marginBottom + paddingTop + paddingBottom;

// check if the currentYPosition has enough space for the new Paragraph
if ((currentYPosition.getCurrentYPosition() - height) < htmlRectangle.getBottom()) {
// add new page and reset the currentYPosition
pdfPage = pdfDocument.addNewPage();
pages++;
canvas = new Canvas(new PdfCanvas(pdfPage), htmlRectangle);
currentYPosition.setCurrentYPosition(htmlRectangle.getTop());
}

canvas.showTextAligned(p, htmlRectangle.getLeft(), currentYPosition.getCurrentYPosition() - p.getMarginTop().getValue(), txtAlignment);
currentYPosition.setCurrentYPosition(currentYPosition.getCurrentYPosition() - (height + padding));
float paragraphHeight = getBlockElementHeight(blockElement, htmlRectangle);
document.showTextAligned(p, htmlRectangle.getLeft(), currentYPosition.getCurrentYPosition(), txtAlignment);
currentYPosition.setCurrentYPosition(currentYPosition.getCurrentYPosition() - paragraphHeight);
} else if (blockElement instanceof Table){
Table table = (Table) blockElement;
float tableHeight = getBlockElementHeight(blockElement, htmlRectangle);
table.setFixedPosition(page, htmlRectangle.getX(), currentYPosition.getCurrentYPosition() - tableHeight, htmlRectangle.getWidth());
currentYPosition.setCurrentYPosition(currentYPosition.getCurrentYPosition() - tableHeight);
document.add(table);
} else if (blockElement instanceof com.itextpdf.layout.element.List){
com.itextpdf.layout.element.List list = (com.itextpdf.layout.element.List) blockElement;
float listHeight = getBlockElementHeight(blockElement, htmlRectangle);
list.setFixedPosition(page, htmlRectangle.getX(),currentYPosition.getCurrentYPosition() - listHeight, htmlRectangle.getWidth());
currentYPosition.setCurrentYPosition(currentYPosition.getCurrentYPosition() - listHeight);
document.add(list);
} else if (blockElement instanceof Div) {
Div div = (Div) blockElement;
// Iterate through the children of the Div
// Iterate through the children of the Div and process each child element recursively
for (IElement child : div.getChildren())
if (child instanceof IBlockElement)
// Process the child element recursively
processHTMLElement(canvas,htmlRectangle, currentYPosition, txtAlignment, (IBlockElement) child);
processHTMLElement(htmlRectangle, currentYPosition, txtAlignment, (IBlockElement) child);
}
}

private float getBlockElementHeight(IBlockElement blockElement, Rectangle htmlRectangle) throws RuntimeException{
if (blockElement instanceof Paragraph){
Paragraph p = (Paragraph) blockElement;
return p.createRendererSubTree().setParent(document.getRenderer()).layout(new LayoutContext(new LayoutArea(page, htmlRectangle))).getOccupiedArea().getBBox().getHeight();
} else if (blockElement instanceof Table){
Table table = (Table) blockElement;
return table.createRendererSubTree().setParent(document.getRenderer()).layout(new LayoutContext(new LayoutArea(page, htmlRectangle))).getOccupiedArea().getBBox().getHeight();
} else if (blockElement instanceof com.itextpdf.layout.element.List){
com.itextpdf.layout.element.List list = (com.itextpdf.layout.element.List) blockElement;
return list.createRendererSubTree().setParent(document.getRenderer()).layout(new LayoutContext(new LayoutArea(page, htmlRectangle))).getOccupiedArea().getBBox().getHeight();
}
throw new RuntimeException("getBlockElementHeight failed to calculate the height of the block element");
}

public class YPosition {
float currentYPosition;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ else if (valign == PDFReportPDFBox.VerticalAlign.BOTTOM.value())
boolean autoResize = (align & 256) == 256;

if (htmlformat == 1) {
//As for now, HTML printing is not supported
log.info("As for now, HTML printing is not supported while generating reports using PDFBox");
}
else
if (barcodeType != null){
Expand Down