您的代码并不是真正独立的(我无法运行它,因为它特别错过了输入数据),所以我只能做一些 PDF Clown 代码分析。但是,该代码分析确实出现了一个 PDF Clown 实现细节,可以解释您的观察。
PDF Clown 如何计算标注标注的尺寸?
标记注释矩形必须足够大,以包含所有四边形以及开始和结束装饰(标记矩形上的圆形左右大写字母)。
PDF Clown 计算这个矩形如下TextMarkup
:
public void setMarkupBoxes(
List<Quad> value
)
{
PdfArray quadPointsObject = new PdfArray();
double pageHeight = getPage().getBox().getHeight();
Rectangle2D box = null;
for(Quad markupBox : value)
{
/*
NOTE: Despite the spec prescription, Point 3 and Point 4 MUST be inverted.
*/
Point2D[] markupBoxPoints = markupBox.getPoints();
quadPointsObject.add(PdfReal.get(markupBoxPoints[0].getX())); // x1.
quadPointsObject.add(PdfReal.get(pageHeight - markupBoxPoints[0].getY())); // y1.
quadPointsObject.add(PdfReal.get(markupBoxPoints[1].getX())); // x2.
quadPointsObject.add(PdfReal.get(pageHeight - markupBoxPoints[1].getY())); // y2.
quadPointsObject.add(PdfReal.get(markupBoxPoints[3].getX())); // x4.
quadPointsObject.add(PdfReal.get(pageHeight - markupBoxPoints[3].getY())); // y4.
quadPointsObject.add(PdfReal.get(markupBoxPoints[2].getX())); // x3.
quadPointsObject.add(PdfReal.get(pageHeight - markupBoxPoints[2].getY())); // y3.
if(box == null)
{box = markupBox.getBounds2D();}
else
{box.add(markupBox.getBounds2D());}
}
getBaseDataObject().put(PdfName.QuadPoints, quadPointsObject);
/*
NOTE: Box width is expanded to make room for end decorations (e.g. rounded highlight caps).
*/
double markupBoxMargin = getMarkupBoxMargin(box.getHeight());
box.setRect(box.getX() - markupBoxMargin, box.getY(), box.getWidth() + markupBoxMargin * 2, box.getHeight());
setBox(box);
refreshAppearance();
}
private static double getMarkupBoxMargin(
double boxHeight
)
{return boxHeight * .25;}
因此,它采用所有四边形的边界框并添加左右边距,每个边距宽度为整个边界框高度的四分之一。
你的情况是什么结果?
虽然如果只有一个四边形,这种添加的边距宽度是明智的,但如果您的标记注释包含许多相互重叠的四边形,这会导致巨大的、不必要的边距。
如何改进代码?
由于添加的大写取决于单个大写而不是它们的组合边界框,因此可以通过使用单个四边形的最大高度而不是所有四边形的边界框的高度来改进代码,例如:
Rectangle2D box = null;
double maxQuadHeight = 0;
for(Quad markupBox : value)
{
double quadHeight = markupBox.getBounds2D().getHeight();
if (quadHeight > maxQuadHeight)
maxQuadHeight = quadHeight;
...
}
...
double markupBoxMargin = getMarkupBoxMargin(maxQuadHeight);
box.setRect(box.getX() - markupBoxMargin, box.getY(), box.getWidth() + markupBoxMargin * 2, box.getHeight());
setBox(box);
如果您不想为此修补 PDF Clown,您也可以在构造TextMarkup _textMarkup
纠正预先计算的注释矩形后执行此代码(稍作修改)。
这是在修复 PDF Clown 错误吗?
这不是错误,因为文本标记注释矩形不需要最小;PDF Clown 还可以始终为每个此类注释使用整个裁剪框。
不过,我会假设代码的作者想要计算一个最小的矩形,但只针对单行进行了优化,因此在某种程度上没有达到他自己的期望......
这段代码还有其他问题吗?
是的。标记注释标记的文本不必是水平的,它可能有一个角度,甚至可以是垂直的。在这种情况下,注释矩形的顶部和底部也需要一些边距,而不是(仅)在左侧和右侧。