problems = PdfVisualTester.comparePdfDocuments(expectedPdfBytes, actualPdfBytes, resource, false);
+
+ if (!problems.isEmpty()) {
+ System.err.println("Found problems with test case (" + resource + "):");
+ System.err.println(problems.stream().map(p -> p.logMessage).collect(Collectors.joining("\n ", "[\n ", "\n]")));
+
+ File outPdf = new File(outputPath, resource + "---actual.pdf");
+ Files.write(outPdf.toPath(), actualPdfBytes);
+ }
+
+ if (problems.stream().anyMatch(p -> p.testImages != null)) {
+ System.err.println("For test case (" + resource + ") writing diff images to '" + outputPath + "'");
+ }
+
+ for (PdfCompareResult result : problems) {
+ if (result.testImages != null) {
+ File output = new File(outputPath, resource + "---" + result.pageNumber + "---diff.png");
+ ImageIO.write(result.testImages.createDiff(), "png", output);
+
+ output = new File(outputPath, resource + "---" + result.pageNumber + "---actual.png");
+ ImageIO.write(result.testImages.getActual(), "png", output);
+
+ output = new File(outputPath, resource + "---" + result.pageNumber + "---expected.png");
+ ImageIO.write(result.testImages.getExpected(), "png", output);
+ }
+ }
+
+ return problems.isEmpty();
+ }
}
diff --git a/openhtmltopdf-examples/src/main/resources/visualtest/expected/issue-427-body-page-positions.pdf b/openhtmltopdf-examples/src/main/resources/visualtest/expected/issue-427-body-page-positions.pdf
new file mode 100644
index 000000000..7b1862801
Binary files /dev/null and b/openhtmltopdf-examples/src/main/resources/visualtest/expected/issue-427-body-page-positions.pdf differ
diff --git a/openhtmltopdf-examples/src/main/resources/visualtest/html/issue-427-body-page-positions.html b/openhtmltopdf-examples/src/main/resources/visualtest/html/issue-427-body-page-positions.html
new file mode 100644
index 000000000..9a9d98817
--- /dev/null
+++ b/openhtmltopdf-examples/src/main/resources/visualtest/html/issue-427-body-page-positions.html
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+Page one
+This is a test!
+
+Fixed layer
+
+This is page two.
+
+Absolute layer on page two
+
+This is page three.
+
+
+ Relative
+
Abs in rel
+
+
+
+
diff --git a/openhtmltopdf-examples/src/test/java/com/openhtmltopdf/nonvisualregressiontests/NonVisualRegressionTest.java b/openhtmltopdf-examples/src/test/java/com/openhtmltopdf/nonvisualregressiontests/NonVisualRegressionTest.java
index cc0c5bf60..a23dc6599 100644
--- a/openhtmltopdf-examples/src/test/java/com/openhtmltopdf/nonvisualregressiontests/NonVisualRegressionTest.java
+++ b/openhtmltopdf-examples/src/test/java/com/openhtmltopdf/nonvisualregressiontests/NonVisualRegressionTest.java
@@ -6,9 +6,11 @@
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
+import java.awt.Color;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -24,6 +26,8 @@
import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
+import org.apache.pdfbox.pdmodel.PDPageContentStream;
+import org.apache.pdfbox.pdmodel.PDPageContentStream.AppendMode;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo;
import org.apache.pdfbox.pdmodel.interactive.action.PDActionURI;
@@ -42,7 +46,10 @@
import org.junit.Assert;
import org.junit.Test;
+import com.openhtmltopdf.layout.Layer;
import com.openhtmltopdf.outputdevice.helper.ExternalResourceControlPriority;
+import com.openhtmltopdf.pdfboxout.PagePosition;
+import com.openhtmltopdf.pdfboxout.PdfBoxRenderer;
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
import com.openhtmltopdf.testcases.TestcaseRunner;
import com.openhtmltopdf.util.Diagnostic;
@@ -71,20 +78,30 @@ private static void render(String fileName, String html, BuilderConfig config) t
System.err.println("Failed to render resource (" + fileName + ")");
e.printStackTrace();
}
-
+
+ writePdfToFile(fileName, actual);
+ }
+
+ private static void writePdfToFile(String fileName, ByteArrayOutputStream actual) throws IOException {
FileUtils.writeByteArrayToFile(new File(OUT_PATH, fileName + ".pdf"), actual.toByteArray());
}
-
- private static PDDocument run(String fileName, BuilderConfig config) throws IOException {
+
+ private static String loadHtml(String fileName) throws IOException {
String absResPath = RES_PATH + fileName + ".html";
-
- byte[] htmlBytes = IOUtils
- .toByteArray(TestcaseRunner.class.getResourceAsStream(absResPath));
-
- String html = new String(htmlBytes, Charsets.UTF_8);
+
+ try (InputStream is = TestcaseRunner.class.getResourceAsStream(absResPath)) {
+ byte[] htmlBytes = IOUtils
+ .toByteArray(is);
+
+ return new String(htmlBytes, Charsets.UTF_8);
+ }
+ }
+
+ private static PDDocument run(String fileName, BuilderConfig config) throws IOException {
+ String html = loadHtml(fileName);
render(fileName, html, config);
-
+
return load(fileName);
}
@@ -1093,6 +1110,65 @@ public void testIssue508FileEmbed() throws IOException {
}
}
+ /**
+ * Tests the PdfBoxRenderer::getPagePositions and
+ * PdfBoxRenderer::getLastYPositionOfContent apis.
+ * It does this by drawing a rect around each layer and comparing
+ * with the expected document.
+ */
+ @Test
+ public void testIssue427GetBodyPagePositions() throws IOException {
+ String filename = "issue-427-body-page-positions";
+ String html = loadHtml(filename);
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+ PdfRendererBuilder builder = new PdfRendererBuilder();
+
+ builder.withHtmlContent(html, null);
+ builder.useFastMode();
+ builder.toStream(os);
+
+ float lastContentLine;
+
+ try (PdfBoxRenderer renderer = builder.buildPdfRenderer()) {
+ renderer.createPDFWithoutClosing();
+
+ List> posList = renderer.getLayersPositions();
+ lastContentLine = renderer.getLastContentBottom();
+
+ int i = -1;
+ PDPageContentStream stream = null;
+ for (PagePosition pos : posList) {
+ if (i != pos.getPageNo()) {
+ if (stream != null) {
+ stream.close();
+ }
+
+ stream = new PDPageContentStream(renderer.getPdfDocument(),
+ renderer.getPdfDocument().getPage(pos.getPageNo()), AppendMode.APPEND, false, false);
+ stream.setLineWidth(1f);
+ stream.setStrokingColor(Color.ORANGE);
+
+ i = pos.getPageNo();
+ }
+
+
+ stream.addRect(pos.getX(), pos.getY(), pos.getWidth(), pos.getHeight());
+ stream.stroke();
+ }
+
+ if (stream != null) {
+ stream.close();
+ }
+
+ renderer.getPdfDocument().save(os);
+ writePdfToFile(filename, os);
+ }
+
+ assertTrue(TestSupport.comparePdfs(os.toByteArray(), filename));
+ assertEquals(111.48, lastContentLine, 0.5);
+ }
+
// TODO:
// + More form controls.
// + Custom meta info.
diff --git a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PagePosition.java b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PagePosition.java
index 3b86fd819..f4af94342 100644
--- a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PagePosition.java
+++ b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PagePosition.java
@@ -19,59 +19,57 @@
*/
package com.openhtmltopdf.pdfboxout;
-public class PagePosition {
- private String _id;
- private int _pageNo;
- private float _x;
- private float _width;
- private float _y;
- private float _height;
-
+public class PagePosition {
+ private final String _id;
+ private final T _element;
+ private final int _pageNo;
+ private final float _x;
+ private final float _y;
+ private final float _width;
+ private final float _height;
+
+ public PagePosition(String id, T element, int pageNo, float x, float y, float width, float height) {
+ this._id = id;
+ this._element = element;
+ this._pageNo = pageNo;
+ this._x = x;
+ this._y = y;
+ this._width = width;
+ this._height = height;
+ }
+
public int getPageNo() {
return _pageNo;
}
-
- public void setPageNo(int pageNo) {
- _pageNo = pageNo;
- }
-
+
public float getX() {
return _x;
}
-
- public void setX(float x) {
- _x = x;
- }
-
- public float getWidth() {
- return _width;
- }
-
- public void setWidth(float width) {
- _width = width;
- }
-
+
public float getY() {
return _y;
}
-
- public void setY(float y) {
- _y = y;
+
+ public float getWidth() {
+ return _width;
}
-
+
public float getHeight() {
return _height;
}
-
- public void setHeight(float height) {
- _height = height;
- }
public String getId() {
return _id;
}
- public void setId(String id) {
- _id = id;
+ public T getElement() {
+ return _element;
+ }
+
+ @Override
+ public String toString() {
+ return String.format(
+ "PagePosition [_id=%s, _element=%s, _pageNo=%s, _x=%s, _y=%s, _width=%s, _height=%s]",
+ _id, _element, _pageNo, _x, _y, _width, _height);
}
}
diff --git a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxFastOutputDevice.java b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxFastOutputDevice.java
index 157b2eb02..0dc93b0c1 100644
--- a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxFastOutputDevice.java
+++ b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxFastOutputDevice.java
@@ -53,8 +53,6 @@
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
-import org.apache.pdfbox.pdmodel.graphics.image.JPEGFactory;
-import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.graphics.shading.PDShading;
import org.apache.pdfbox.pdmodel.graphics.state.RenderingMode;
@@ -71,6 +69,7 @@
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
public class PdfBoxFastOutputDevice extends AbstractOutputDevice implements OutputDevice, PdfBoxOutputDevice {
//
@@ -1182,34 +1181,23 @@ protected PDFont mapFont(Font font, IFontTextDrawerEnv env) {
}
}
- public List findPagePositionsByID(CssContext c, Pattern pattern) {
+ public List> findPagePositionsByID(CssContext c, Pattern pattern) {
Map idMap = _sharedContext.getIdMap();
if (idMap == null) {
return Collections.emptyList();
}
- List result = new ArrayList<>();
- for (Entry entry : idMap.entrySet()) {
- String id = (String) entry.getKey();
- if (pattern.matcher(id).find()) {
- Box box = (Box) entry.getValue();
- PagePosition pos = calcPDFPagePosition(c, id, box);
- if (pos != null) {
- result.add(pos);
- }
- }
- }
-
- Collections.sort(result, new Comparator() {
- public int compare(PagePosition p1, PagePosition p2) {
- return p1.getPageNo() - p2.getPageNo();
- }
- });
-
- return result;
+ return
+ idMap.entrySet()
+ .stream()
+ .filter(entry -> pattern.matcher(entry.getKey()).find())
+ .map(entry -> calcPDFPagePosition(c, entry.getKey(), entry.getValue()))
+ .filter(Objects::nonNull)
+ .sorted(Comparator.comparing(PagePosition::getPageNo))
+ .collect(Collectors.toList());
}
- private PagePosition calcPDFPagePosition(CssContext c, String id, Box box) {
+ private PagePosition calcPDFPagePosition(CssContext c, String id, Box box) {
PageBox page = _root.getLayer().getLastPage(c, box);
if (page == null) {
return null;
@@ -1220,15 +1208,8 @@ private PagePosition calcPDFPagePosition(CssContext c, String id, Box box) {
x /= _dotsPerPoint;
y /= _dotsPerPoint;
- PagePosition result = new PagePosition();
- result.setId(id);
- result.setPageNo(page.getPageNo());
- result.setX(x);
- result.setY(y);
- result.setWidth(box.getEffectiveWidth() / _dotsPerPoint);
- result.setHeight(box.getHeight() / _dotsPerPoint);
-
- return result;
+ return new PagePosition(
+ id, box, page.getPageNo(), x, y, box.getEffectiveWidth() / _dotsPerPoint, box.getHeight() / _dotsPerPoint);
}
@Override
diff --git a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxOutputDevice.java b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxOutputDevice.java
index ead654683..320adab2b 100644
--- a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxOutputDevice.java
+++ b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxOutputDevice.java
@@ -183,7 +183,7 @@ void drawStringFast(String s, float x, float y, JustificationInfo info,
void drawWithGraphics(float x, float y, float width, float height,
OutputDeviceGraphicsDrawer renderer);
- List findPagePositionsByID(CssContext c, Pattern pattern);
+ List> findPagePositionsByID(CssContext c, Pattern pattern);
void setRenderingContext(RenderingContext result);
diff --git a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxRenderer.java b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxRenderer.java
index 28ebfdb77..c09d54933 100644
--- a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxRenderer.java
+++ b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxRenderer.java
@@ -35,23 +35,23 @@
import com.openhtmltopdf.outputdevice.helper.ExternalResourceControlPriority;
import com.openhtmltopdf.outputdevice.helper.ExternalResourceType;
import com.openhtmltopdf.extend.FSDOMMutator;
-import com.openhtmltopdf.outputdevice.helper.NullUserInterface;
import com.openhtmltopdf.outputdevice.helper.PageDimensions;
import com.openhtmltopdf.outputdevice.helper.UnicodeImplementation;
import com.openhtmltopdf.pdfboxout.PdfBoxSlowOutputDevice.Metadata;
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder.CacheStore;
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder.PdfAConformance;
import com.openhtmltopdf.render.BlockBox;
+import com.openhtmltopdf.render.Box;
import com.openhtmltopdf.render.PageBox;
import com.openhtmltopdf.render.RenderingContext;
import com.openhtmltopdf.render.ViewportBox;
import com.openhtmltopdf.render.displaylist.DisplayListCollector;
import com.openhtmltopdf.render.displaylist.DisplayListContainer;
import com.openhtmltopdf.render.displaylist.DisplayListPainter;
+import com.openhtmltopdf.render.displaylist.PagedBoxCollector;
import com.openhtmltopdf.render.displaylist.DisplayListContainer.DisplayListPageContainer;
import com.openhtmltopdf.resource.XMLResource;
import com.openhtmltopdf.simple.extend.XhtmlNamespaceHandler;
-import com.openhtmltopdf.util.Configuration;
import com.openhtmltopdf.util.LogMessageId;
import com.openhtmltopdf.util.ThreadCtx;
import com.openhtmltopdf.util.XRLog;
@@ -83,10 +83,15 @@
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
import java.util.logging.Level;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
public class PdfBoxRenderer implements Closeable, PageSupplier {
// See discussion of units at top of PdfBoxOutputDevice.
@@ -1037,7 +1042,7 @@ public float getDotsPerPoint() {
return _dotsPerPoint;
}
- public List findPagePositionsByID(Pattern pattern) {
+ public List> findPagePositionsByID(Pattern pattern) {
return _outputDevice.findPagePositionsByID(newLayoutContext(), pattern);
}
@@ -1108,4 +1113,185 @@ public PDPage requestPage(PDDocument doc, float pageWidth, float pageHeight, int
doc.addPage(page);
return page;
}
+
+ /**
+ * Start page to end page and then top to bottom on page.
+ */
+ private final Comparator> PAGE_POSITION_COMPARATOR =
+ Comparator.comparingInt(PagePosition>::getPageNo)
+ .thenComparing(Comparator.comparingDouble(PagePosition>::getY).reversed());
+
+ /**
+ * Returns the bottom Y postion in bottom-up PDF units
+ * on the last page of content.
+ *
+ * WARNING: NOT transform aware.
+ */
+ public float getLastContentBottom() {
+ List> positions = getLayersPositions();
+
+ if (positions.isEmpty()) {
+ return 0;
+ }
+
+ return positions.get(positions.size() - 1).getY();
+ }
+
+ /**
+ * Returns a list of page positions for all layers in the document.
+ * The page positions are sorted from first page to last and then top to bottom.
+ * The page position values are in bottom-up PDF units.
+ *
+ * WARNING: NOT transform aware. Transformed layers will return page
+ * positions that are not correct.
+ */
+ public List> getLayersPositions() {
+ if (getRootBox() == null) {
+ this.layout();
+ }
+
+ Layer rootLayer = getRootBox().getLayer();
+
+ int[] whiches = new int[] { Layer.NEGATIVE, Layer.AUTO, Layer.ZERO, Layer.POSITIVE };
+
+ List layers =
+ Arrays.stream(whiches)
+ .mapToObj(rootLayer::collectLayers)
+ .flatMap(List::stream)
+ .collect(Collectors.toList());
+
+ RenderingContext ctx = newRenderingContext();
+ List pages = rootLayer.getPages();
+
+ List> ret = new ArrayList<>();
+
+ ret.addAll(getLayerPagePositions(rootLayer, pages, ctx));
+
+ layers.stream()
+ .map(layer -> getLayerPagePositions(layer, pages, ctx))
+ .forEach(ret::addAll);
+
+ Collections.sort(ret, PAGE_POSITION_COMPARATOR);
+
+ return ret;
+ }
+
+ /**
+ * Returns a list of page positions for a single layer.
+ * The page positions are sorted from first page to last and then top to bottom.
+ * The page position values are in bottom-up PDF units.
+ *
+ * Compare to {@link #getLayersPositions()} which will return page
+ * positions for all layers.
+ *
+ * WARNING: NOT transform aware. A transformed layer will return page
+ * positions that are not correct.
+ */
+ public List> getLayerPositions(Layer layer) {
+ RenderingContext ctx = newRenderingContext();
+ List pages = layer.getPages();
+
+ List> ret = getLayerPagePositions(layer, pages, ctx);
+
+ Collections.sort(ret, PAGE_POSITION_COMPARATOR);
+
+ return ret;
+ }
+
+ private List> getLayerPagePositions(
+ Layer layer, List pages, RenderingContext ctx) {
+
+ // FIXME: This method is not transform aware.
+
+ Box box = layer.getMaster();
+
+ int start = findStartPage(ctx, layer, pages);
+ int end = findEndPage(ctx, layer, pages);
+
+ if (box.getStyle().isFixed()) {
+ PageBox page = pages.get(start);
+
+ float x = box.getAbsX() + page.getMarginBorderPadding(ctx, CalculatedStyle.LEFT);
+ float w = box.getEffectiveWidth();
+ float y = page.getMarginBorderPadding(ctx, CalculatedStyle.BOTTOM) +
+ (page.getPaintingBottom() - box.getAbsY() - box.getHeight());
+ float h = box.getHeight();
+
+ return IntStream.range(0, pages.size())
+ .mapToObj(pageNo -> createPagePosition(null, layer, pageNo, x, y, w, h))
+ .collect(Collectors.toList());
+ }
+
+ List> ret = new ArrayList<>((end - start) + 1);
+
+ for (int i = start; i <= end; i++) {
+ PageBox page = pages.get(i);
+
+ float x = box.getAbsX() + page.getMarginBorderPadding(ctx, CalculatedStyle.LEFT);
+ float w = box.getEffectiveWidth();
+
+ float y;
+ float h;
+
+ if (start != end) {
+ if (i != start && i != end) {
+ y = page.getMarginBorderPadding(ctx, CalculatedStyle.BOTTOM);
+ h = page.getContentHeight(ctx);
+ } else if (i == end) {
+ h = (box.getAbsY() + box.getHeight()) - page.getPaintingTop();
+ y = page.getMarginBorderPadding(ctx, CalculatedStyle.BOTTOM) +
+ page.getContentHeight(ctx) - h;
+ } else {
+ assert i == start;
+ y = page.getMarginBorderPadding(ctx, CalculatedStyle.BOTTOM);
+ h = page.getPaintingBottom() - box.getAbsY();
+ }
+ } else {
+ y = page.getMarginBorderPadding(ctx, CalculatedStyle.BOTTOM) +
+ (page.getPaintingBottom() - box.getAbsY() - box.getHeight());
+ h = box.getHeight();
+ }
+
+ PagePosition pos = createPagePosition(null, layer, i, x, y, w, h);
+
+ ret.add(pos);
+ }
+
+ return ret;
+ }
+
+ private PagePosition createPagePosition(
+ String id, T element, int pageNo, float x, float y, float w, float h) {
+
+ return new PagePosition<>(
+ id, element, pageNo, x / _dotsPerPoint, y / _dotsPerPoint, w / _dotsPerPoint, h / _dotsPerPoint);
+ }
+
+ /**
+ * Returns the start page for a layer. Transform aware.
+ */
+ private int findStartPage(RenderingContext c, Layer layer, List pages) {
+ int start = PagedBoxCollector.findStartPage(c, layer.getMaster(), pages);
+
+ // Floats maybe outside the master box.
+ for (BlockBox floater : layer.getFloats()) {
+ start = Math.min(start, PagedBoxCollector.findStartPage(c, floater, pages));
+ }
+
+ return start;
+ }
+
+ /**
+ * Returns the end page number for a layer. Transform aware.
+ */
+ private int findEndPage(RenderingContext c, Layer layer, List pages) {
+ int end = PagedBoxCollector.findEndPage(c, layer.getMaster(), pages);
+
+ // Floats may be outside the master box.
+ for (BlockBox floater : layer.getFloats()) {
+ end = Math.max(end, PagedBoxCollector.findEndPage(c, floater, pages));
+ }
+
+ return end;
+ }
}
diff --git a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxSlowOutputDevice.java b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxSlowOutputDevice.java
index ffeb754e0..2156e3bb4 100644
--- a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxSlowOutputDevice.java
+++ b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxSlowOutputDevice.java
@@ -1326,26 +1326,26 @@ protected PDFont mapFont(Font font, IFontTextDrawerEnv env) {
}
}
- public List findPagePositionsByID(CssContext c, Pattern pattern) {
+ public List> findPagePositionsByID(CssContext c, Pattern pattern) {
Map idMap = _sharedContext.getIdMap();
if (idMap == null) {
return Collections.emptyList();
}
- List result = new ArrayList<>();
+ List> result = new ArrayList<>();
for (Entry entry : idMap.entrySet()) {
String id = (String) entry.getKey();
if (pattern.matcher(id).find()) {
Box box = (Box) entry.getValue();
- PagePosition pos = calcPDFPagePosition(c, id, box);
+ PagePosition pos = calcPDFPagePosition(c, id, box);
if (pos != null) {
result.add(pos);
}
}
}
- Collections.sort(result, new Comparator() {
- public int compare(PagePosition p1, PagePosition p2) {
+ Collections.sort(result, new Comparator>() {
+ public int compare(PagePosition p1, PagePosition p2) {
return p1.getPageNo() - p2.getPageNo();
}
});
@@ -1353,7 +1353,7 @@ public int compare(PagePosition p1, PagePosition p2) {
return result;
}
- private PagePosition calcPDFPagePosition(CssContext c, String id, Box box) {
+ private PagePosition calcPDFPagePosition(CssContext c, String id, Box box) {
PageBox page = _root.getLayer().getLastPage(c, box);
if (page == null) {
return null;
@@ -1364,15 +1364,8 @@ private PagePosition calcPDFPagePosition(CssContext c, String id, Box box) {
x /= _dotsPerPoint;
y /= _dotsPerPoint;
- PagePosition result = new PagePosition();
- result.setId(id);
- result.setPageNo(page.getPageNo());
- result.setX(x);
- result.setY(y);
- result.setWidth(box.getEffectiveWidth() / _dotsPerPoint);
- result.setHeight(box.getHeight() / _dotsPerPoint);
-
- return result;
+ return new PagePosition<>(
+ id, box, page.getPageNo(), x, y, box.getEffectiveWidth() / _dotsPerPoint, box.getHeight() / _dotsPerPoint);
}
public void setRenderingContext(RenderingContext result) {