Skip to content

Commit c053a04

Browse files
author
Samuel Huylebroeck
committed
Improve flushing of HtmlDocumentRenderer
add tests Fixes for autoport DEVSIX-3102
1 parent d326b01 commit c053a04

File tree

5 files changed

+192
-10
lines changed

5 files changed

+192
-10
lines changed

src/main/java/com/itextpdf/html2pdf/attach/impl/layout/HtmlDocumentRenderer.java

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -191,11 +191,7 @@ public void addChild(IRenderer renderer) {
191191
*/
192192
@Override
193193
public void close() {
194-
if (waitingElement != null) {
195-
IRenderer r = this.waitingElement;
196-
waitingElement = null;
197-
super.addChild(r);
198-
}
194+
processWaitingElement();
199195
super.close();
200196
trimLastPageIfNecessary();
201197
document.getPdfDocument().removeEventHandler(PdfDocumentEvent.END_PAGE, handler);
@@ -213,10 +209,7 @@ public void close() {
213209
@Override
214210
public IRenderer getNextRenderer() {
215211
// Process waiting element to get the correct number of pages
216-
if (waitingElement != null) {
217-
super.addChild(waitingElement);
218-
waitingElement = null;
219-
}
212+
processWaitingElement();
220213
HtmlDocumentRenderer relayoutRenderer = new HtmlDocumentRenderer(document, immediateFlush);
221214
PageSize defaultPageSize = document.getPdfDocument().getDefaultPageSize();
222215
float[] defaultPageMargins = {document.getTopMargin(), document.getRightMargin(), document.getBottomMargin(), document.getRightMargin()};
@@ -228,6 +221,20 @@ public IRenderer getNextRenderer() {
228221
return relayoutRenderer;
229222
}
230223

224+
@Override
225+
public void flush(){
226+
processWaitingElement();
227+
super.flush();
228+
}
229+
230+
void processWaitingElement(){
231+
if (waitingElement != null) {
232+
IRenderer r = this.waitingElement;
233+
waitingElement = null;
234+
super.addChild(r);
235+
}
236+
}
237+
231238
boolean shouldAttemptTrimLastPage() {
232239
return TRIM_LAST_BLANK_PAGE && document.getPdfDocument().getNumberOfPages() > 1;
233240
}

src/test/java/com/itextpdf/html2pdf/css/PageRuleTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ public void marginBoxRunningNoImmediateFlush03() throws IOException, Interrupted
626626
}
627627

628628
@Test
629-
@LogMessages(messages = @LogMessage(messageTemplate = com.itextpdf.io.LogMessageConstant.REMOVING_PAGE_HAS_ALREADY_BEEN_FLUSHED, count = 4))
629+
@LogMessages(messages = @LogMessage(messageTemplate = com.itextpdf.io.LogMessageConstant.REMOVING_PAGE_HAS_ALREADY_BEEN_FLUSHED, count = 6))
630630
public void marginBoxRunningNoImmediateFlush04() throws IOException, InterruptedException {
631631
String name = "marginBoxRunningNoImmediateFlush04";
632632
String htmlPath = sourceFolder + name + ".html";
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2019 iText Group NV
4+
Authors: iText Software.
5+
6+
This program is free software; you can redistribute it and/or modify
7+
it under the terms of the GNU Affero General Public License version 3
8+
as published by the Free Software Foundation with the addition of the
9+
following permission added to Section 15 as permitted in Section 7(a):
10+
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
11+
ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
12+
OF THIRD PARTY RIGHTS
13+
14+
This program is distributed in the hope that it will be useful, but
15+
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16+
or FITNESS FOR A PARTICULAR PURPOSE.
17+
See the GNU Affero General Public License for more details.
18+
You should have received a copy of the GNU Affero General Public License
19+
along with this program; if not, see http://www.gnu.org/licenses or write to
20+
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21+
Boston, MA, 02110-1301 USA, or download the license from the following URL:
22+
http://itextpdf.com/terms-of-use/
23+
24+
The interactive user interfaces in modified source and object code versions
25+
of this program must display Appropriate Legal Notices, as required under
26+
Section 5 of the GNU Affero General Public License.
27+
28+
In accordance with Section 7(b) of the GNU Affero General Public License,
29+
a covered work must retain the producer line in every PDF that is created
30+
or manipulated using iText.
31+
32+
You can be released from the requirements of the license by purchasing
33+
a commercial license. Buying such a license is mandatory as soon as you
34+
develop commercial activities involving the iText software without
35+
disclosing the source code of your own applications.
36+
These activities include: offering paid services to customers as an ASP,
37+
serving PDFs on the fly in a web application, shipping iText with a closed
38+
source product.
39+
40+
For more information, please contact iText Software Corp. at this
41+
42+
*/
43+
package com.itextpdf.html2pdf.events;
44+
45+
import com.itextpdf.html2pdf.ConverterProperties;
46+
import com.itextpdf.html2pdf.HtmlConverter;
47+
import com.itextpdf.io.util.UrlUtil;
48+
import com.itextpdf.kernel.events.Event;
49+
import com.itextpdf.kernel.events.IEventHandler;
50+
import com.itextpdf.kernel.events.PdfDocumentEvent;
51+
import com.itextpdf.kernel.geom.Rectangle;
52+
import com.itextpdf.kernel.pdf.PdfDocument;
53+
import com.itextpdf.kernel.pdf.PdfPage;
54+
import com.itextpdf.kernel.pdf.PdfWriter;
55+
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
56+
import com.itextpdf.kernel.pdf.xobject.PdfFormXObject;
57+
import com.itextpdf.kernel.utils.CompareTool;
58+
import com.itextpdf.layout.Canvas;
59+
import com.itextpdf.layout.Document;
60+
import com.itextpdf.layout.element.Paragraph;
61+
import com.itextpdf.layout.property.TextAlignment;
62+
import com.itextpdf.test.ExtendedITextTest;
63+
import com.itextpdf.test.annotations.type.IntegrationTest;
64+
import org.junit.Assert;
65+
import org.junit.BeforeClass;
66+
import org.junit.Test;
67+
import org.junit.experimental.categories.Category;
68+
69+
import java.io.File;
70+
import java.io.FileInputStream;
71+
import java.io.IOException;
72+
73+
@Category(IntegrationTest.class)
74+
public class PdfHtmlPageXofYEventHandlerTest extends ExtendedITextTest {
75+
76+
public static final String sourceFolder = "./src/test/resources/com/itextpdf/html2pdf/events/PdfHtmlPageXofYEventHandlerTest/";
77+
public static final String destinationFolder = "./target/test/com/itextpdf/html2pdf/events/PdfHtmlPageXofYEventHandlerTest/";
78+
79+
@BeforeClass
80+
public static void beforeClass() {
81+
createDestinationFolder(destinationFolder);
82+
}
83+
84+
@Test
85+
public void pageXofYHtmlTest() throws IOException, InterruptedException {
86+
String filename = "pageXofY";
87+
String src = sourceFolder + filename + ".html";
88+
String dest = destinationFolder + filename + ".pdf";
89+
String cmp = sourceFolder + "cmp_" + filename + ".pdf";
90+
new PdfHtmlPageXofYEventHandlerTest().parseWithFooter(src, dest, sourceFolder);
91+
System.out.println("html: file:///" + UrlUtil.toNormalizedURI(src).getPath() + "\n");
92+
Assert.assertNull(new CompareTool().compareByContent(dest, cmp, destinationFolder, "diff_XofY_"));
93+
94+
}
95+
96+
public void parseWithFooter(String htmlSource, String pdfDest, String resoureLoc) throws IOException, InterruptedException {
97+
//Create Document
98+
PdfWriter writer = new PdfWriter(pdfDest);
99+
PdfDocument pdfDocument = new PdfDocument(writer);
100+
//Create event-handlers
101+
PageXofY footerHandler = new PageXofY(pdfDocument);
102+
//Assign event-handlers
103+
pdfDocument.addEventHandler(PdfDocumentEvent.END_PAGE, footerHandler);
104+
//Convert
105+
ConverterProperties converterProperties = new ConverterProperties().setBaseUri(resoureLoc);
106+
Document doc = HtmlConverter.convertToDocument(new FileInputStream(new File(htmlSource).getAbsolutePath()), pdfDocument, converterProperties);
107+
//Write the total number of pages to the placeholder
108+
doc.flush();
109+
footerHandler.writeTotal(pdfDocument);
110+
doc.close();
111+
}
112+
113+
//page X of Y
114+
protected class PageXofY implements IEventHandler {
115+
protected PdfFormXObject placeholder;
116+
protected float side = 20;
117+
protected float x = 300;
118+
protected float y = 25;
119+
protected float space = 4.5f;
120+
protected float descent = 3;
121+
122+
public PageXofY(PdfDocument pdf) {
123+
placeholder =
124+
new PdfFormXObject(new Rectangle(0, 0, side, side));
125+
}
126+
127+
@Override
128+
public void handleEvent(Event event) {
129+
PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
130+
PdfDocument pdf = docEvent.getDocument();
131+
PdfPage page = docEvent.getPage();
132+
int pageNumber = pdf.getPageNumber(page);
133+
Rectangle pageSize = page.getPageSize();
134+
PdfCanvas pdfCanvas = new PdfCanvas(
135+
page.getLastContentStream(), page.getResources(), pdf);
136+
Canvas canvas = new Canvas(pdfCanvas, pdf, pageSize);
137+
Paragraph p = new Paragraph()
138+
.add("Page ").add(String.valueOf(pageNumber)).add(" of");
139+
canvas.showTextAligned(p, x, y, TextAlignment.RIGHT);
140+
pdfCanvas.addXObject(placeholder, x + space, y - descent);
141+
canvas.close();
142+
}
143+
144+
public void writeTotal(PdfDocument pdf) {
145+
Canvas canvas = new Canvas(placeholder, pdf);
146+
canvas.showTextAligned(String.valueOf(pdf.getNumberOfPages()),
147+
0, descent, TextAlignment.LEFT);
148+
}
149+
}
150+
151+
152+
}

0 commit comments

Comments
 (0)