diff --git a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxFastLinkManager.java b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxFastLinkManager.java index 5a5fb3147..df1ce8c87 100644 --- a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxFastLinkManager.java +++ b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxFastLinkManager.java @@ -14,8 +14,6 @@ import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.common.PDRectangle; -import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDObjectReference; -import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureElement; import org.apache.pdfbox.pdmodel.interactive.action.PDAction; import org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo; import org.apache.pdfbox.pdmodel.interactive.action.PDActionJavaScript; @@ -270,19 +268,27 @@ private boolean placeAnnotation(AffineTransform transform, Shape linkShape, Rect annot.setPrinted(true); if (linkShape != null) { - float[] quadPoints = mapShapeToQuadPoints(transform, linkShape, targetArea); + QuadPointShape quadPointsResult = mapShapeToQuadPoints(transform, linkShape, targetArea); /* * Is this not an area shape? Then we can not setup quads - ignore this shape. */ - if (quadPoints.length == 0) + if (quadPointsResult.quadPoints.length == 0) return false; - annot.setQuadPoints(quadPoints); + annot.setQuadPoints(quadPointsResult.quadPoints); + Rectangle2D reducedTarget = quadPointsResult.boundingBox; + annot.setRectangle(new PDRectangle((float) reducedTarget.getMinX(), (float) reducedTarget.getMinY(), + (float) reducedTarget.getWidth(), (float) reducedTarget.getHeight())); } return true; } - static float[] mapShapeToQuadPoints(AffineTransform transform, Shape linkShape, Rectangle2D targetArea) { - List points = new ArrayList(); + static class QuadPointShape { + float[] quadPoints; + Rectangle2D boundingBox; + } + + static QuadPointShape mapShapeToQuadPoints(AffineTransform transform, Shape linkShape, Rectangle2D targetArea) { + List points = new ArrayList<>(); AffineTransform transformForQuads = new AffineTransform(); transformForQuads.translate(targetArea.getMinX(), targetArea.getMinY()); // We must flip the whole thing upside down @@ -318,6 +324,11 @@ static float[] mapShapeToQuadPoints(AffineTransform transform, Shape linkShape, KongAlgo algo = new KongAlgo(points); algo.runKong(); + float minX = (float) targetArea.getMaxX(); + float maxX = (float) targetArea.getMinX(); + float minY = (float) targetArea.getMaxY(); + float maxY = (float) targetArea.getMinY(); + float[] ret = new float[algo.getTriangles().size() * 8]; int i = 0; for (Triangle triangle : algo.getTriangles()) { @@ -333,6 +344,17 @@ static float[] mapShapeToQuadPoints(AffineTransform transform, Shape linkShape, ret[i++] = triangle.c.x; ret[i++] = triangle.c.y; + + for (Point2D.Float p : new Point2D.Float[] { triangle.a, triangle.b, triangle.c }) { + float x = p.x; + float y = p.y; + + minX = Math.min(x, minX); + minY = Math.min(y, minY); + + maxX = Math.max(x, maxX); + maxY = Math.max(y, maxY); + } } //noinspection ConstantConditions @@ -341,10 +363,17 @@ static float[] mapShapeToQuadPoints(AffineTransform transform, Shape linkShape, for (; i < ret.length; i += 2) { if (ret[i] < targetArea.getMinX() || ret[i] > targetArea.getMaxX()) throw new IllegalStateException("Invalid rectangle calculation. Map shape is out of bound."); - if (ret[i + 1] < targetArea.getMinY() || ret[i + 1] > targetArea.getMaxY()) + if (ret[i + 1] < targetArea.getMinY() || ret[ + i + 1] > targetArea.getMaxY()) throw new IllegalStateException("Invalid rectangle calculation. Map shape is out of bound."); } - return ret; + + QuadPointShape result = new QuadPointShape(); + result.quadPoints = ret; + Rectangle2D.Float boundingRectangle = new Rectangle2D.Float(minX, minY, maxX - minX, maxY - minY); + Rectangle.intersect(targetArea, boundingRectangle, boundingRectangle); + result.boundingBox = boundingRectangle; + return result; } private void addLinkToPage(PDPage page, PDAnnotationLink annot, Box anchor, Box target) { diff --git a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxLinkManager.java b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxLinkManager.java index d789be74a..5e02b1adf 100644 --- a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxLinkManager.java +++ b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxLinkManager.java @@ -4,8 +4,6 @@ import com.openhtmltopdf.extend.NamespaceHandler; import com.openhtmltopdf.extend.ReplacedElement; import com.openhtmltopdf.layout.SharedContext; -import com.openhtmltopdf.pdfboxout.quads.KongAlgo; -import com.openhtmltopdf.pdfboxout.quads.Triangle; import com.openhtmltopdf.render.BlockBox; import com.openhtmltopdf.render.Box; import com.openhtmltopdf.render.PageBox; @@ -255,13 +253,16 @@ private boolean placeAnnotation(AffineTransform transform, Shape linkShape, Rect annot.setRectangle(new PDRectangle((float) targetArea.getMinX(), (float) targetArea.getMinY(), (float) targetArea.getWidth(), (float) targetArea.getHeight())); if (linkShape != null) { - float[] quadPoints = mapShapeToQuadPoints(transform, linkShape, targetArea); + PdfBoxFastLinkManager.QuadPointShape quadPointsResult = mapShapeToQuadPoints(transform, linkShape, targetArea); /* * Is this not an area shape? Then we can not setup quads - ignore this shape. */ - if (quadPoints.length == 0) + if (quadPointsResult.quadPoints.length == 0) return false; - annot.setQuadPoints(quadPoints); + annot.setQuadPoints(quadPointsResult.quadPoints); + Rectangle2D reducedTarget = quadPointsResult.boundingBox; + annot.setRectangle(new PDRectangle((float) reducedTarget.getMinX(), (float) reducedTarget.getMinY(), + (float) reducedTarget.getWidth(), (float) reducedTarget.getHeight())); } return true; }