Author: msahyoun Date: Fri Feb 2 16:46:52 2018 New Revision: 1822987 URL: http://svn.apache.org/viewvc?rev=1822987&view=rev Log: PDFBOX-3353: correct calculations for annotation /Rect, /RD and borderBox; align handling for empty /RD with Adobe Reader
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAbstractAppearanceHandler.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDSquareAppearanceHandler.java Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAbstractAppearanceHandler.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAbstractAppearanceHandler.java?rev=1822987&r1=1822986&r2=1822987&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAbstractAppearanceHandler.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAbstractAppearanceHandler.java Fri Feb 2 16:46:52 2018 @@ -185,6 +185,49 @@ public abstract class PDAbstractAppearan return new PDRectangle(rectangle.getLowerLeftX() + padding, rectangle.getLowerLeftY() + padding, rectangle.getWidth() - 2 * padding, rectangle.getHeight() - 2 * padding); } + + /** + * Get a rectangle enlarged by the differences. + * + * <p>Creates a new rectangle with differences added to each side. + * . + * @param rectangle the rectangle. + * @param diifferences the differences to apply. + * @return the padded rectangle. + */ + PDRectangle addRectDifferences(PDRectangle rectangle, float[] differences) + { + if (differences == null || differences.length != 4) + { + return rectangle; + } + + return new PDRectangle(rectangle.getLowerLeftX() - differences[0], + rectangle.getLowerLeftY() - differences[1], + rectangle.getWidth() + differences[0] + differences[2], + rectangle.getHeight() + differences[1] + differences[3]); + } + + /** + * Get a rectangle with the differences applied to each side. + * + * <p>Creates a new rectangle with differences added to each side. + * . + * @param rectangle the rectangle. + * @param diifferences the differences to apply. + * @return the padded rectangle. + */ + PDRectangle applyRectDifferences(PDRectangle rectangle, float[] differences) + { + if (differences == null || differences.length != 4) + { + return rectangle; + } + return new PDRectangle(rectangle.getLowerLeftX() + differences[0], + rectangle.getLowerLeftY() + differences[1], + rectangle.getWidth() - differences[0] - differences[2], + rectangle.getHeight() - differences[1] - differences[3]); + } void handleOpacity(float opacity) throws IOException { Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDSquareAppearanceHandler.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDSquareAppearanceHandler.java?rev=1822987&r1=1822986&r2=1822987&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDSquareAppearanceHandler.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDSquareAppearanceHandler.java Fri Feb 2 16:46:52 2018 @@ -68,15 +68,34 @@ public class PDSquareAppearanceHandler e contentStream.setBorderLine(lineWidth, annotation.getBorderStyle()); - // the differences rectangle - // TODO: this only works for border effect solid. Cloudy needs a different approach. - setRectDifference(lineWidth); + // handle the border box + // + // There are two options. The handling is not part of the PDF specification but + // implementation specific to Adobe Reader + // - if /RD is set the border box is the /Rect entry inset by the respective + // border difference. + // - if /RD is not set the border box is defined by the /Rect entry. The /RD entry will + // be set to be the line width and the /Rect is enlarged by the /RD amount + + PDRectangle borderBox = null; + float[] rectDifferences = annotation.getRectDifferences(); - // Acrobat applies a padding to each side of the bbox so the line is completely within - // the bbox. - PDRectangle borderEdge = getPaddedRectangle(getRectangle(),lineWidth); - contentStream.addRect(borderEdge.getLowerLeftX(), borderEdge.getLowerLeftY(), - borderEdge.getWidth(), borderEdge.getHeight()); + if (rectDifferences.length == 0) + { + borderBox = getPaddedRectangle(getRectangle(), lineWidth/2); + // the differences rectangle + // TODO: this only works for border effect solid. Cloudy needs a different approach. + annotation.setRectDifferences(lineWidth/2); + annotation.setRectangle(addRectDifferences(getRectangle(), annotation.getRectDifferences())); + } + else + { + borderBox = applyRectDifferences(getRectangle(), rectDifferences); + borderBox = getPaddedRectangle(borderBox, lineWidth/2); + } + + contentStream.addRect(borderBox.getLowerLeftX(), borderBox.getLowerLeftY(), + borderBox.getWidth(), borderBox.getHeight()); contentStream.drawShape(lineWidth, hasStroke, hasBackground); }