iText中的框云外观

时间:2019-05-31 03:03:07

标签: annotations itext cloud pdf-generation

这是我的示例代码,用于绘制箱形云注释。我在PDFBox的实现中使用了代码来绘制方框云,但是在iText中使用时遇到了一些问题。我修改了边框类和某些部分,使其可以在iText中使用。

您可以找到边界类别here

我的问题是,没有绘制顶部和右侧边界云。看来他们的位置超出了直肠的区别。我认为问题在于在cloudyPolygonImpl()中绘制曲线。也许itext有不同的绘制PdfAppearance的方法吗?我不确定。

这是我到目前为止所拥有的。 boxcloud

    public class Test {
    public static void main(String[] args) throws Exception {
    PdfReader reader = new PdfReader("src.pdf");
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("result.pdf"));

    PdfDictionary be = new PdfDictionary();
    be.put(PdfName.S, PdfName.C);
    be.put(PdfName.I, new PdfNumber(1));

    Rectangle location = new Rectangle(123.6f, 584.4f, 252.6f, 653.4f);
    PdfAnnotation stamp = PdfAnnotation.createSquareCircle(stamper.getWriter(), location, "", true);
    stamp.setBorderStyle(new PdfBorderDictionary(1, PdfBorderDictionary.STYLE_SOLID));
    stamp.put(new PdfName("BE"), be);
    stamp.setColor(BaseColor.RED);

    PdfContentByte cb = stamper.getOverContent(1);
    PdfAppearance app = cb.createAppearance(location.getWidth(), location.getHeight());
    stamp.setAppearance(PdfName.N, app);

    PdfArray stickyRect = stamp.getAsArray(PdfName.RECT);
    Rectangle annotRect = new Rectangle(stickyRect.getAsNumber(0).floatValue(),
        stickyRect.getAsNumber(1).floatValue(),
        stickyRect.getAsNumber(2).floatValue(),
        stickyRect.getAsNumber(3).floatValue());

    // Create cloud appearance
    CBorder cborder = new CBorder(app, 1, 1, annotRect);
    cborder.createCloudyRectangle(null);

    stamp.put(PdfName.RECT, new PdfRectangle(cborder.getRectangle()));
    stamp.put(PdfName.RD, new PdfArray(new float[] { 
        cborder.getRectDifference().getLeft(), 
        cborder.getRectDifference().getBottom(), 
        cborder.getRectDifference().getRight(), 
        cborder.getRectDifference().getTop() }));

    app.rectangle(cborder.getBBox());
    app.transform(cborder.getMatrix());


    app.setColorStroke(BaseColor.RED);
    app.setLineWidth(1);
    app.stroke();

    stamper.addAnnotation(stamp, 1);
    stamper.close();
    reader.close();
}    
    }

正确的输出应该是所有边界都用云绘制,但是目前只绘制左侧和底部。

1 个答案:

答案 0 :(得分:1)

(此答案基于revision 3 of your question中的代码,因为revision 4中的更改引入了多个错误。)

您的代码在此处创建了无效的注释外观流:

CBorder cborder = new CBorder(app, 1, 1, annotRect);
cborder.createCloudyRectangle(null);

stamp.put(PdfName.RECT, new PdfRectangle(cborder.getRectangle()));
stamp.put(PdfName.RD, new PdfArray(new float[] { 
    cborder.getRectDifference().getLeft(), 
    cborder.getRectDifference().getBottom(), 
    cborder.getRectDifference().getRight(), 
    cborder.getRectDifference().getTop() }));

app.rectangle(cborder.getBBox());
app.transform(cborder.getMatrix());


app.setColorStroke(BaseColor.RED);
app.setLineWidth(1);
app.stroke();

其上部创建路径:

2 j
121.58 588.63 m
122.06 588.95 122.6 589.18 123.16 589.3 c
120.73 588.78 119.18 586.4 119.7 583.96 c
120.19 581.67 122.35 580.14 124.68 580.44 c
...
122.06 596.42 122.6 596.64 123.16 596.76 c
121.09 596.32 119.6 594.49 119.6 592.36 c
119.6 590.87 120.34 589.47 121.58 588.63 c
h

然后app.rectangle(cborder.getBBox())不创建任何内容(请注意,此rectangle重载不是您期望的!)。

然后app.transform(cborder.getMatrix())将更改添加到当前的变换矩阵中,app.setColorStroke(BaseColor.RED)添加了更改的笔触颜色,app.setLineWidth(1)添加了更改的线宽:

1 0 0 1 -118.68 -579.48 cm
1 0 0 RG
1 w

最后app.stroke()添加命令来描画路径:

S

但是在路径定义和相应的路径绘制命令之间,仅允许剪切路径指令! cf.图9 –图形对象–在PDF规范ISO 32000-1中。

您可以像这样修复此代码,提取颜色和线条宽度的变化,并直接使用云边界框:

// Create cloud appearance
app.setColorStroke(BaseColor.RED);
app.setLineWidth(1);

CBorder cborder = new CBorder(app, 1, 1, annotRect);
cborder.createCloudyRectangle(null);

stamp.put(PdfName.RECT, new PdfRectangle(cborder.getRectangle()));
stamp.put(PdfName.RD, new PdfArray(new float[] { 
    cborder.getRectDifference().getLeft(), 
    cborder.getRectDifference().getBottom(), 
    cborder.getRectDifference().getRight(), 
    cborder.getRectDifference().getTop() }));

app.stroke();
app.setBoundingBox(cborder.getBBox());

CloudBoxAnnotation测试testDrawLikeChitgoksImproved

这尤其会更改

的结果(如Adobe Acrobat中所示)

Screenshot original

Screenshot fix