Может кто-нибудь объяснить, пожалуйста, порядок рисования на холсте iTexts?

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

Так что у меня есть несколько таблиц внутри другой таблицы, которые имеют цвет фона и / или обводки (через PdfPCellEvents). К сожалению, штрихи внешнего стола перекрывают фон внутреннего стола. Я предполагаю, что это происходит из-за неправильного порядка применения или некоторого неправильного набора saveState или же restoreState в моих PdfPCellEvents.

Может ли кто-нибудь объяснить правильное использование saveState а также restoreState и дайте мне подсказку, как правильно наносить фоны и штрихи?

Вот мой код для добавления ячейки с полосатым фоном:

PdfPCell scaleBackground = new PdfPCell();
scaleBackground.setBorder(Rectangle.NO_BORDER);
scaleBackground.setVerticalAlignment(Element.ALIGN_TOP);
scaleBackground.setCellEvent(new StripedScaleBackground(max, scaleHeight));

Метод cellLayout StripedScaleBackground:

public void cellLayout(PdfPCell cell, Rectangle rect, PdfContentByte[] canvases)
{
    PdfContentByte canvas = canvases[PdfPTable.LINECANVAS];
    float llx = rect.getLeft();
    float lly = rect.getBottom();
    float urx = rect.getRight();
    float ury = rect.getTop();

    // Light scale lines with padding from left
    canvas.setLineWidth(Constants.BORDER_WIDTH_THIN);
    canvas.setColorStroke(Colors.LIGHT_GRAY);

    float paddingLeft = 22f;
    for (int i = 0; i <= this.maxValue; i++)
    {
        canvas.moveTo(llx + paddingLeft, lly + (this.scaleHeight * (i + 1)));
        canvas.lineTo(urx, lly + (this.scaleHeight * (i + 1)));
    }

    // Vertical line
    canvas.moveTo(llx + (((urx - llx) + paddingLeft) / 2), ury);
    canvas.lineTo(llx + (((urx - llx) + paddingLeft) / 2), lly);
    canvas.stroke();

    // Fat line left and right
    canvas.moveTo(llx, ury);
    canvas.lineTo(llx, lly);
    canvas.moveTo(urx, ury);
    canvas.lineTo(urx, lly);

    canvas.setLineWidth(0.8f);
    canvas.setColorStroke(Colors.MEDIUM_GRAY);
    canvas.stroke();

    canvas.saveState();
    canvas.restoreState();
}

Гистограммы представляют собой таблицы, где в каждой ячейке есть событие ячейки для градиента и границы. Гистограммы добавляются в scaleBackground PdfPCell первого куска кода и имеет следующие PdfPCellEvents (пример черной части диаграммы):

public void cellLayout(PdfPCell cell, Rectangle rect, PdfContentByte[] canvases)
{
    PdfContentByte backgroundCanvas = canvases[PdfPTable.BACKGROUNDCANVAS];
    float llx = rect.getLeft();
    float lly = rect.getBottom();
    float urx = rect.getRight();
    float ury = rect.getTop();

    // Draw background

    // Define shading with direction and color
    PdfShading shading = PdfShading.simpleAxial(this.writer,
                    llx, ury,
                    llx, lly,
                    Colors.BAR_CHART_BLACK_LIGHT, Colors.BAR_CHART_BLACK_DARK);

    PdfShadingPattern pattern = new PdfShadingPattern(shading);
    backgroundCanvas.setShadingFill(pattern);

    // Draw shape with defined shading
    backgroundCanvas.moveTo(llx, ury);
    backgroundCanvas.lineTo(llx, lly);
    backgroundCanvas.lineTo(urx, lly);
    backgroundCanvas.lineTo(urx, ury);
    backgroundCanvas.lineTo(llx, ury);
    backgroundCanvas.fill();

    backgroundCanvas.saveState();
    backgroundCanvas.restoreState();

    // Draw border
    PdfContentByte lineCanvas = canvases[PdfPTable.LINECANVAS];

    float lineWidth = Constants.BORDER_WIDTH_THIN;
    lineCanvas.setLineWidth(lineWidth);
    lineCanvas.moveTo(llx, ury - lineWidth);
    lineCanvas.lineTo(llx, lly);
    lineCanvas.lineTo(urx, lly);
    lineCanvas.lineTo(urx, ury - lineWidth);

    lineCanvas.setColorStroke(BaseColor.BLACK);
    lineCanvas.stroke();

    lineCanvas.saveState();
    lineCanvas.restoreState();
}

1 ответ

Это порядок различных прямых слоев контента:

  • PdfPtable.BASECANVAS- Все, что находится здесь, будет под столом.
  • PdfPtable.BACKGROUNDCANVAS—Это слой, где нарисованы фоны.
  • PdfPtable.LINECANVAS—Это слой, где нарисованы линии.
  • PdfPtable.TEXTCANVAS—Это слой, куда идет текст. Все, что здесь размещено, покроет стол.

Это было взято из книги "iText в действии - второе издание".

Вы также спрашиваете о saveState() а также restoreState(), Это объясняется в главе 2 учебника по iText 7:

Сначала мы сохраняем текущее графическое состояние с помощью saveState() метод, затем мы меняем состояние и рисуем любые линии или фигуры, которые мы хотим нарисовать, наконец, мы используем restoreState() метод возврата к исходному графическому состоянию. Все изменения, которые мы применили после saveState() будет отменен Это особенно интересно, если вы меняете несколько значений (ширина линии, цвет,...) или когда трудно рассчитать обратное изменение (возврат к исходной системе координат).

Ваш код был слишком длинным для меня, чтобы проверить, но я очень сомневаюсь, что saveState()/restoreState() будет причиной вашей проблемы.

Я бы постарался максимально избежать вложенности таблиц. Обычно гораздо проще (и эффективнее) использовать colspan и rowspan.

Если это не решит вашу проблему, пожалуйста, объясните вашу проблему в одном предложении.

Другие вопросы по тегам