Search code examples
c#itext7

How to correct obsolete code for creating Canvas


This code using iText7 runs. It copies a PDF file and, on the copy, prints a rectangle on top of page 1 with a red border around a text id or message:

        public static void InsertIdPdf(string sourceFilename, string targetFilename, string idText)
        {
            if (idText.Length > 0)
            {
                PdfDocument sourcePdf = new PdfDocument(new PdfReader(sourceFilename));
                PdfDocument targetPdf = new PdfDocument(new PdfWriter(targetFilename));

                sourcePdf.CopyPagesTo(1, sourcePdf.GetNumberOfPages(), targetPdf);
                Document document = new Document(targetPdf, new PageSize(PageSize.A4));

                PdfPage firstPage = targetPdf.GetFirstPage();
                iText.Kernel.Geom.Rectangle pageSize = firstPage.GetCropBox().MoveUp(4);
                Canvas canvas = new Canvas(new PdfCanvas(firstPage, true), targetPdf, pageSize);

                PdfFont idFont = PdfFontFactory.CreateFont(StandardFonts.HELVETICA);
                Style idStyle = new Style()
                    .SetFont(idFont)
                    .SetFontSize(8)
                    .SetPaddingRight(3)
                    .SetTextAlignment(iText.Layout.Properties.TextAlignment.RIGHT)
                    .SetBackgroundColor(ColorConstants.WHITE);

                Paragraph paragraph = new Paragraph(idText)
                    .SetBorder(new SolidBorder(ColorConstants.RED, (float)0.7))
                    .AddStyle(idStyle);
                IRenderer renderer = paragraph.CreateRendererSubTree();
                renderer.SetParent(document.GetRenderer()).Layout(new LayoutContext(new LayoutArea(1, pageSize)));

                canvas.Add(paragraph);
                document.Close();
                sourcePdf.Close();
                targetPdf.Close();
            }
        }

However, iText7 claims this line to be obsolete because the last argument, the Rectangle, may be removed in a future version:

Canvas canvas = new Canvas(new PdfCanvas(firstPage, true), targetPdf, pageSize);

I've tried to adjust the line, removing pageSize to satisfy iText7, but then the rectangle will print below the normal text on the page and flipped (mirrored) vertically.

  1. So, how to adjust the line to not be obsolete and still print the rectangle at the top?

Also, notice the .MoveUp(4) for pageSize. The value 4 is an empiric value that moves the rectangle to the absolute top of the page. If omitted, the rectangle will be positioned with a small gab to the top of the page. This gab is independent of the font size.

  1. So, why 4? I dislike magic numbers and would prefer a calculated value. What expression could be used to calculate this value?

Reference is the two questions here at SO:

Adding page number text to pdf copy gets flipped/mirrored with iText7

iText7: How to get the real width of a Paragraph


Solution

  • I wasn't able to reproduce this but I am now. I think it was something about the printable area of the document I was trying.

    That's aside, the adjustment of the obsolete part is pretty simple. Just change

    Canvas canvas = new Canvas(new PdfCanvas(firstPage, true), targetPdf, pageSize);
    

    to

    Canvas canvas = new Canvas(new PdfCanvas(firstPage, true), pageSize);
    

    The obsoletion is the pdfDocument parameter.

    About the magic number 4. I think it is about the DPI, I really don't know what it is. But the most relevant resource I could find is already in the community: Points -> pixels iText (im)precision