Появление аннотации Cloud Box в iText - PullRequest
1 голос
/ 31 мая 2019

Это мой пример кода для рисования аннотации в облаке. Я использовал код в реализации PDFBox для рисования облака, но у меня возникла небольшая проблема при использовании в iText. Я изменил класс границы и некоторые части, чтобы их можно было использовать в iText.

Вы можете найти границу класса здесь .

Моя проблема в том, что верхняя и правая границы облаков не прорисованы. кажется, что их местоположение нарисовано за пределами прямой разницы Я думаю, что проблема заключается в рисовании кривых в 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());

    PdfArray arrDiff = annotation.getAsArray(PdfName.RD);
    Rectangle annotRectDiff = null;
    if (arrDiff != null) {
            annotRectDiff = new Rectangle(arrDiff.getAsNumber(0).floatValue(), arrDiff.getAsNumber(1).floatValue(),
        arrDiff.getAsNumber(2).floatValue(), arrDiff.getAsNumber(3).floatValue()
    }

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

    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 Ответ

1 голос
/ 04 июня 2019

(Этот ответ основан на коде в редакции 3 вашего вопроса , поскольку изменения в редакции 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

Но между определением пути и соответствующей командой рисования пути разрешены только инструкции обтравочного контура! Ср Рисунок 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

...