Why does the cell background color affect the color of other lines?

Tags: tablescell backgroundgraphics statesave / restore stateiText 7

I'm creating a PDF where I add some text to each page as well as 2 lines that are drawn using the following method:

private void DrawLines(Document pdfDoc, PdfContentByte cb) {
    cb.MoveTo(0, 562);
    cb.LineTo(pdfDoc.PageSize.Width, 562);
    cb.MoveTo(0, 561);
    cb.LineTo(pdfDoc.PageSize.Width, 561);
}
On one specific page, there's a table where I'm using the following code to change the background color for one particular cell:

header = new PdfPCell(new Phrase(market_data_list[i], grid_data_heading));
header.Colspan = 2;
header.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER;
header.BackgroundColor =new BaseColor(238,233,233);
market_table.AddCell(header); //adds cell to the table
I now get the cell with the background color I specified (grey), but the lines change from black to grey... I want to draw those lines in black!

Posted on StackOverflow on Oct 28, 2014 by Annadate Piyush There are two problems with your code:

Problem #1: the method DrawLines() doesnt' draw any lines.

It creates the paths for two lines, but the lines are not drawn by that method. You need to add the following line:

cb.Stroke();

Without that line, drawing the lines is postponed until the stroke operator is called. That may never happen, in which case, the lines are never drawn. In your case, it happens when other content is drawn. By that time, the stroke color may have changed, in which case, the color used to draw the paths you've constructed in your DrawLines() method is unpredictable.

Problem #2: you don't use best practices.

The colors that will be used to draw lines and shapes in your code are unpredictable because you aren't careful with the graphics state stack. Best practices would be to save and restore the graphics state when changing colors, line widths, etc...

I would change your DrawLines() method like this (I’ll write my sample in Java):

private void drawLines(PdfDocument pdfDoc) {
    PdfCanvas canvas = new PdfCanvas(pdfDoc.getFirstPage());
    float width = pdfDoc.getFirstPage().getPageSize().getWidth();
    canvas.saveState()
            .setStrokeColor(Color.DARK_GRAY)
            .moveTo(0, 562)
            .lineTo(width, 562)
            .moveTo(0, 561)
            .lineTo(width, 561)
            .stroke()
            .restoreState();
}

As you see, there is no PdfContentByte in iText 7. You should create PdfCanvas object from any desired page in the document (I’ve used the first one) and draw content directly to it. Before you start you should use saveState() method. When you finish make sure that the changes you applied don't affect other content you might be adding, don’t forget the restoreState() method.

Click this link if you want to see how to answer this question in iText 5.