Skip to content

Commit e1a2380

Browse files
SnipxiText-CI
authored andcommitted
Prepare TargetCounterHandler to used from pure layout code
DEVSIX-5502
1 parent a009bcd commit e1a2380

File tree

4 files changed

+107
-16
lines changed

4 files changed

+107
-16
lines changed

layout/src/main/java/com/itextpdf/layout/Document.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,10 @@ public void relayout() {
204204
throw new IllegalStateException("Operation not supported with immediate flush");
205205
}
206206

207+
if (rootRenderer instanceof DocumentRenderer) {
208+
((DocumentRenderer) rootRenderer).getTargetCounterHandler().prepareHandlerToRelayout();
209+
}
210+
207211
IRenderer nextRelayoutRenderer = rootRenderer != null ? rootRenderer.getNextRenderer() : null;
208212
if (nextRelayoutRenderer == null || !(nextRelayoutRenderer instanceof RootRenderer)) {
209213
nextRelayoutRenderer = new DocumentRenderer(this, immediateFlush);

layout/src/main/java/com/itextpdf/layout/renderer/DocumentRenderer.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ public LayoutArea getOccupiedArea() {
108108
*/
109109
@Override
110110
public IRenderer getNextRenderer() {
111-
return new DocumentRenderer(document, immediateFlush);
111+
DocumentRenderer renderer = new DocumentRenderer(document, immediateFlush);
112+
renderer.targetCounterHandler = new TargetCounterHandler(targetCounterHandler);
113+
return renderer;
112114
}
113115

114116
protected LayoutArea updateCurrentArea(LayoutResult overflowResult) {
@@ -117,7 +119,8 @@ protected LayoutArea updateCurrentArea(LayoutResult overflowResult) {
117119
if (taggingHelper != null) {
118120
taggingHelper.releaseFinishedHints();
119121
}
120-
AreaBreak areaBreak = overflowResult != null && overflowResult.getAreaBreak() != null ? overflowResult.getAreaBreak() : null;
122+
AreaBreak areaBreak = overflowResult != null && overflowResult.getAreaBreak() != null ?
123+
overflowResult.getAreaBreak() : null;
121124
if (areaBreak != null && areaBreak.getType() == AreaBreakType.LAST_PAGE) {
122125
while (currentPageNumber < document.getPdfDocument().getNumberOfPages()) {
123126
moveToNextPage();
@@ -126,7 +129,8 @@ protected LayoutArea updateCurrentArea(LayoutResult overflowResult) {
126129
moveToNextPage();
127130
}
128131
PageSize customPageSize = areaBreak != null ? areaBreak.getPageSize() : null;
129-
while (document.getPdfDocument().getNumberOfPages() >= currentPageNumber && document.getPdfDocument().getPage(currentPageNumber).isFlushed()) {
132+
while (document.getPdfDocument().getNumberOfPages() >= currentPageNumber &&
133+
document.getPdfDocument().getPage(currentPageNumber).isFlushed()) {
130134
currentPageNumber++;
131135
}
132136
PageSize lastPageSize = ensureDocumentHasNPages(currentPageNumber, customPageSize);
@@ -156,14 +160,16 @@ protected void flushSingleRenderer(IRenderer resultRenderer) {
156160
}
157161

158162
boolean wrapOldContent = pdfDocument.getReader() != null && pdfDocument.getWriter() != null &&
159-
correspondingPage.getContentStreamCount() > 0 && correspondingPage.getLastContentStream().getLength() > 0 &&
163+
correspondingPage.getContentStreamCount() > 0 &&
164+
correspondingPage.getLastContentStream().getLength() > 0 &&
160165
!wrappedContentPage.contains(pageNum) && pdfDocument.getNumberOfPages() >= pageNum;
161166
wrappedContentPage.add(pageNum);
162167

163168
if (pdfDocument.isTagged()) {
164169
pdfDocument.getTagStructureContext().getAutoTaggingPointer().setPageForTagging(correspondingPage);
165170
}
166-
resultRenderer.draw(new DrawContext(pdfDocument, new PdfCanvas(correspondingPage, wrapOldContent), pdfDocument.isTagged()));
171+
resultRenderer.draw(new DrawContext(pdfDocument,
172+
new PdfCanvas(correspondingPage, wrapOldContent), pdfDocument.isTagged()));
167173
}
168174
}
169175

@@ -178,7 +184,7 @@ protected PageSize addNewPage(PageSize customPageSize) {
178184

179185
/**
180186
* Adds some pages so that the overall number is at least n.
181-
* Returns the page size of the n'th page.
187+
* Returns the page size of the page number {@code n}.
182188
*/
183189
private PageSize ensureDocumentHasNPages(int n, PageSize customPageSize) {
184190
PageSize lastPageSize = null;
@@ -200,8 +206,8 @@ private Rectangle getCurrentPageEffectiveArea(PageSize pageSize) {
200206
}
201207

202208
private void moveToNextPage() {
203-
// We don't flush this page immediately, but only flush previous one because of manipulations with areas in case
204-
// of keepTogether property.
209+
// We don't flush this page immediately, but only flush previous one because of manipulations
210+
// with areas in case of keepTogether property.
205211
if (immediateFlush && currentPageNumber > 1) {
206212
document.getPdfDocument().getPage(currentPageNumber - 1).flush();
207213
}

layout/src/test/java/com/itextpdf/layout/renderer/TargetCounterHandlerTest.java

Lines changed: 89 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,30 +25,46 @@ This file is part of the iText (R) project.
2525
import com.itextpdf.io.font.constants.StandardFonts;
2626
import com.itextpdf.io.image.ImageDataFactory;
2727
import com.itextpdf.kernel.font.PdfFontFactory;
28+
import com.itextpdf.kernel.geom.PageSize;
2829
import com.itextpdf.kernel.geom.Rectangle;
30+
import com.itextpdf.kernel.pdf.PdfDocument;
31+
import com.itextpdf.kernel.pdf.PdfWriter;
32+
import com.itextpdf.kernel.utils.CompareTool;
33+
import com.itextpdf.layout.Document;
34+
import com.itextpdf.layout.element.AreaBreak;
2935
import com.itextpdf.layout.element.Div;
3036
import com.itextpdf.layout.element.Image;
3137
import com.itextpdf.layout.element.Paragraph;
3238
import com.itextpdf.layout.element.Table;
3339
import com.itextpdf.layout.element.Text;
3440
import com.itextpdf.layout.layout.LayoutArea;
3541
import com.itextpdf.layout.layout.LayoutContext;
42+
import com.itextpdf.layout.layout.LayoutResult;
3643
import com.itextpdf.layout.property.Property;
3744
import com.itextpdf.layout.property.UnitValue;
3845
import com.itextpdf.layout.splitting.DefaultSplitCharacters;
3946
import com.itextpdf.test.ExtendedITextTest;
4047
import com.itextpdf.test.annotations.type.IntegrationTest;
48+
49+
import java.io.IOException;
4150
import org.junit.Assert;
51+
import org.junit.BeforeClass;
4252
import org.junit.Test;
4353
import org.junit.experimental.categories.Category;
4454

45-
import java.io.IOException;
46-
4755
@Category(IntegrationTest.class)
4856
public class TargetCounterHandlerTest extends ExtendedITextTest {
4957

58+
public static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/layout/renderer/TargetCounterHandlerTest/";
59+
public static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/layout/renderer/TargetCounterHandlerTest/";
60+
61+
@BeforeClass
62+
public static void beforeClass() {
63+
createDestinationFolder(DESTINATION_FOLDER);
64+
}
65+
5066
@Test
51-
public void BlockRendererAddByIDTest() {
67+
public void blockRendererAddByIDTest() {
5268
DocumentRenderer documentRenderer = new DocumentRenderer(null);
5369
DivRenderer divRenderer = new DivRenderer(new Div());
5470
divRenderer.setParent(documentRenderer);
@@ -62,7 +78,7 @@ public void BlockRendererAddByIDTest() {
6278
}
6379

6480
@Test
65-
public void TextRendererAddByIDTest() throws IOException {
81+
public void textRendererAddByIDTest() throws IOException {
6682
DocumentRenderer documentRenderer = new DocumentRenderer(null);
6783
TextRenderer textRenderer = new TextRenderer(new Text("a"));
6884

@@ -84,7 +100,7 @@ public void TextRendererAddByIDTest() throws IOException {
84100
}
85101

86102
@Test
87-
public void TableRendererAddByIDTest() {
103+
public void tableRendererAddByIDTest() {
88104
DocumentRenderer documentRenderer = new DocumentRenderer(null);
89105
TableRenderer tableRenderer = new TableRenderer(new Table(5));
90106
tableRenderer.setParent(documentRenderer);
@@ -98,7 +114,7 @@ public void TableRendererAddByIDTest() {
98114
}
99115

100116
@Test
101-
public void ParagraphRendererAddByIDTest() {
117+
public void paragraphRendererAddByIDTest() {
102118
DocumentRenderer documentRenderer = new DocumentRenderer(null);
103119
ParagraphRenderer paragraphRenderer = new ParagraphRenderer(new Paragraph());
104120
paragraphRenderer.setParent(documentRenderer);
@@ -112,7 +128,7 @@ public void ParagraphRendererAddByIDTest() {
112128
}
113129

114130
@Test
115-
public void ImageRendererAddByIDTest() {
131+
public void imageRendererAddByIDTest() {
116132
DocumentRenderer documentRenderer = new DocumentRenderer(null);
117133
ImageRenderer imageRenderer = new ImageRenderer(new Image(ImageDataFactory.createRawImage(new byte[]{50, 21})));
118134
imageRenderer.setParent(documentRenderer);
@@ -126,7 +142,7 @@ public void ImageRendererAddByIDTest() {
126142
}
127143

128144
@Test
129-
public void LineRendererAddByIDTest() {
145+
public void lineRendererAddByIDTest() {
130146
DocumentRenderer documentRenderer = new DocumentRenderer(null);
131147
LineRenderer lineRenderer = new LineRenderer();
132148
lineRenderer.setParent(documentRenderer);
@@ -138,4 +154,69 @@ public void LineRendererAddByIDTest() {
138154
documentRenderer.getTargetCounterHandler().prepareHandlerToRelayout();
139155
Assert.assertEquals((Integer) 4, TargetCounterHandler.getPageByID(lineRenderer, id));
140156
}
157+
158+
@Test
159+
public void targetCounterHandlerEndToEndLayoutTest() throws IOException, InterruptedException {
160+
String targetPdf = DESTINATION_FOLDER + "targetCounterHandlerEndToEndLayoutTest.pdf";
161+
String cmpPdf = SOURCE_FOLDER + "cmp_targetCounterHandlerEndToEndLayoutTest.pdf";
162+
Document document = new Document(new PdfDocument(new PdfWriter(targetPdf)),
163+
PageSize.A4, false);
164+
165+
Text pageNumPlaceholder = new Text("x");
166+
String id = "1";
167+
pageNumPlaceholder.setProperty(Property.ID, id);
168+
pageNumPlaceholder.setNextRenderer(new TargetCounterAwareTextRenderer(pageNumPlaceholder));
169+
Paragraph intro = new Paragraph("The paragraph is on page ").add(pageNumPlaceholder);
170+
document.add(intro);
171+
172+
document.add(new AreaBreak());
173+
Paragraph text = new Paragraph("This is main text");
174+
text.setProperty(Property.ID, id);
175+
text.setNextRenderer(new TargetCounterAwareParagraphRenderer(text));
176+
document.add(text);
177+
178+
document.relayout();
179+
180+
document.close();
181+
182+
Assert.assertNull(new CompareTool().compareByContent(targetPdf, cmpPdf, DESTINATION_FOLDER, "diff"));
183+
}
184+
185+
private static class TargetCounterAwareTextRenderer extends TextRenderer {
186+
public TargetCounterAwareTextRenderer(Text link) {
187+
super(link);
188+
}
189+
190+
@Override
191+
public LayoutResult layout(LayoutContext layoutContext) {
192+
Integer targetPageNumber = TargetCounterHandler.getPageByID(this, this.<String>getProperty(Property.ID));
193+
if (targetPageNumber != null) {
194+
setText(String.valueOf(targetPageNumber));
195+
}
196+
return super.layout(layoutContext);
197+
}
198+
199+
@Override
200+
public IRenderer getNextRenderer() {
201+
return new TargetCounterAwareTextRenderer((Text) getModelElement());
202+
}
203+
}
204+
205+
private static class TargetCounterAwareParagraphRenderer extends ParagraphRenderer {
206+
public TargetCounterAwareParagraphRenderer(Paragraph modelElement) {
207+
super(modelElement);
208+
}
209+
210+
@Override
211+
public IRenderer getNextRenderer() {
212+
return new TargetCounterAwareParagraphRenderer((Paragraph) modelElement);
213+
}
214+
215+
@Override
216+
public LayoutResult layout(LayoutContext layoutContext) {
217+
LayoutResult result = super.layout(layoutContext);
218+
TargetCounterHandler.addPageByID(this);
219+
return result;
220+
}
221+
}
141222
}

0 commit comments

Comments
 (0)