1414
1515import org .apache .pdfbox .pdmodel .PDPage ;
1616import org .apache .pdfbox .pdmodel .common .PDRectangle ;
17- import org .apache .pdfbox .pdmodel .documentinterchange .logicalstructure .PDObjectReference ;
18- import org .apache .pdfbox .pdmodel .documentinterchange .logicalstructure .PDStructureElement ;
1917import org .apache .pdfbox .pdmodel .interactive .action .PDAction ;
2018import org .apache .pdfbox .pdmodel .interactive .action .PDActionGoTo ;
2119import org .apache .pdfbox .pdmodel .interactive .action .PDActionJavaScript ;
@@ -270,25 +268,33 @@ private boolean placeAnnotation(AffineTransform transform, Shape linkShape, Rect
270268 annot .setPrinted (true );
271269
272270 if (linkShape != null ) {
273- float [] quadPoints = mapShapeToQuadPoints (transform , linkShape , targetArea );
271+ QuadPointShape quadPointsResult = mapShapeToQuadPoints (transform , linkShape , targetArea );
274272 /*
275273 * Is this not an area shape? Then we can not setup quads - ignore this shape.
276274 */
277- if (quadPoints .length == 0 )
275+ if (quadPointsResult . quadPoints .length == 0 )
278276 return false ;
279- annot .setQuadPoints (quadPoints );
277+ annot .setQuadPoints (quadPointsResult .quadPoints );
278+ Rectangle2D reducedTarget = quadPointsResult .boundingBox ;
279+ annot .setRectangle (new PDRectangle ((float ) reducedTarget .getMinX (), (float ) reducedTarget .getMinY (),
280+ (float ) reducedTarget .getWidth (), (float ) reducedTarget .getHeight ()));
280281 }
281282 return true ;
282283 }
283284
284- private float [] mapShapeToQuadPoints (AffineTransform transform , Shape linkShape , Rectangle2D targetArea ) {
285- List <Point2D .Float > points = new ArrayList <Point2D .Float >();
285+ static class QuadPointShape {
286+ float [] quadPoints ;
287+ Rectangle2D boundingBox ;
288+ }
289+
290+ static QuadPointShape mapShapeToQuadPoints (AffineTransform transform , Shape linkShape , Rectangle2D targetArea ) {
291+ List <Point2D .Float > points = new ArrayList <>();
286292 AffineTransform transformForQuads = new AffineTransform ();
287293 transformForQuads .translate (targetArea .getMinX (), targetArea .getMinY ());
288294 // We must flip the whole thing upside down
289295 transformForQuads .translate (0 , targetArea .getHeight ());
290296 transformForQuads .scale (1 , -1 );
291- transformForQuads .concatenate (transform );
297+ transformForQuads .concatenate (AffineTransform . getScaleInstance ( transform . getScaleX (), transform . getScaleX ()) );
292298 Area area = new Area (linkShape );
293299 PathIterator pathIterator = area .getPathIterator (transformForQuads , 1.0 );
294300 double [] vals = new double [6 ];
@@ -318,7 +324,12 @@ private float[] mapShapeToQuadPoints(AffineTransform transform, Shape linkShape,
318324 KongAlgo algo = new KongAlgo (points );
319325 algo .runKong ();
320326
321- float ret [] = new float [algo .getTriangles ().size () * 8 ];
327+ float minX = (float ) targetArea .getMaxX ();
328+ float maxX = (float ) targetArea .getMinX ();
329+ float minY = (float ) targetArea .getMaxY ();
330+ float maxY = (float ) targetArea .getMinY ();
331+
332+ float [] ret = new float [algo .getTriangles ().size () * 8 ];
322333 int i = 0 ;
323334 for (Triangle triangle : algo .getTriangles ()) {
324335 ret [i ++] = triangle .a .x ;
@@ -333,17 +344,36 @@ private float[] mapShapeToQuadPoints(AffineTransform transform, Shape linkShape,
333344
334345 ret [i ++] = triangle .c .x ;
335346 ret [i ++] = triangle .c .y ;
347+
348+ for (Point2D .Float p : new Point2D .Float [] { triangle .a , triangle .b , triangle .c }) {
349+ float x = p .x ;
350+ float y = p .y ;
351+
352+ minX = Math .min (x , minX );
353+ minY = Math .min (y , minY );
354+
355+ maxX = Math .max (x , maxX );
356+ maxY = Math .max (y , maxY );
357+ }
336358 }
337359
360+ //noinspection ConstantConditions
338361 if (ret .length % 8 != 0 )
339362 throw new IllegalStateException ("Not exact 8xn QuadPoints!" );
340363 for (; i < ret .length ; i += 2 ) {
341364 if (ret [i ] < targetArea .getMinX () || ret [i ] > targetArea .getMaxX ())
342365 throw new IllegalStateException ("Invalid rectangle calculation. Map shape is out of bound." );
343- if (ret [i + 1 ] < targetArea .getMinY () || ret [i + 1 ] > targetArea .getMaxY ())
366+ if (ret [i + 1 ] < targetArea .getMinY () || ret [
367+ i + 1 ] > targetArea .getMaxY ())
344368 throw new IllegalStateException ("Invalid rectangle calculation. Map shape is out of bound." );
345369 }
346- return ret ;
370+
371+ QuadPointShape result = new QuadPointShape ();
372+ result .quadPoints = ret ;
373+ Rectangle2D .Float boundingRectangle = new Rectangle2D .Float (minX , minY , maxX - minX , maxY - minY );
374+ Rectangle .intersect (targetArea , boundingRectangle , boundingRectangle );
375+ result .boundingBox = boundingRectangle ;
376+ return result ;
347377 }
348378
349379 private void addLinkToPage (PDPage page , PDAnnotationLink annot , Box anchor , Box target ) {
0 commit comments