Search code examples
c#pdfsharp

How to add text to an existing PDF with PDFSharp


Using PDFSharp (1.50 or 6.1.0 Preview 2) I'm trying to open an existing pdf, add some text, then save it again.

However at the line that draws the text I'm getting a System.ArgumentException "An item with the same key has already been added."

I do not understand what this error is trying to tell me or how to resolve it.

Commenting out DrawString line allows the new pdf to be writen, but how do I add text to the PDF?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PdfSharp;
using PdfSharp.Pdf.IO;
using PdfSharp.Pdf;
using PdfSharp.Drawing;
using PdfSharp.Fonts;

namespace MakeAPDF
{
    internal class Program
    {
        static void Main(string[] args)
        {

            const string outfilename = @"C:\Test\Out.pdf";
            PdfDocument document = PdfReader.Open(@"C:\Test\In.pdf",PdfDocumentOpenMode.Modify);
            
            // Get an XGraphics object for drawing
            PdfPage page = document.Pages[0];

            XGraphics gfx = XGraphics.FromPdfPage(page);
            // Create a font

            XFont font = new XFont("Verdana", 20, XFontStyle.BoldItalic);
        
            // Draw the text
            // This line triggers System.ArgumentException
            // Message=An item with the same key has already been added.
            gfx.DrawString("Hello, World!", font, XBrushes.Black, new XRect(0, 0, page.Width, page.Height),  XStringFormats.Center);
        
            // Save the document...  
            document.Save(outfilename);
        }
    }
}

STACKTRACE:

 System.ArgumentException
 HResult=0x80070057
 Message=An item with the same key has already been added.
 Source=mscorlib
 StackTrace: 
 at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
 at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
 at PdfSharp.Pdf.Advanced.PdfResourceMap.CollectResourceNames(Dictionary`2 usedResourceNames)
 at PdfSharp.Pdf.Advanced.PdfResources.ExistsResourceNames(String name)
 at PdfSharp.Pdf.Advanced.PdfResources.get_NextExtGStateName()
 at PdfSharp.Pdf.Advanced.PdfResources.AddExtGState(PdfExtGState extGState)
 at PdfSharp.Drawing.Pdf.PdfGraphicsState.RealizeFillColor(XColor color, Boolean overPrint, PdfColorMode colorMode)
 at PdfSharp.Drawing.Pdf.PdfGraphicsState.RealizeBrush(XBrush brush, PdfColorMode colorMode, Int32 renderingMode, Double fontEmSize)
 at PdfSharp.Drawing.Pdf.PdfGraphicsState.RealizeFont(XFont font, XBrush brush, Int32 renderingMode)
 at PdfSharp.Drawing.Pdf.XGraphicsPdfRenderer.Realize(XFont font, XBrush brush, Int32 renderingMode)
 at PdfSharp.Drawing.Pdf.XGraphicsPdfRenderer.DrawString(String s, XFont font, XBrush brush, XRect rect, XStringFormat format)
 at PdfSharp.Drawing.XGraphics.DrawString(String text, XFont font, XBrush brush, XRect layoutRectangle, XStringFormat format)

UPDATE:

I've discovered that the above code works if the PDF I start with is either completely empty or only contains shapes. If the PDF already contains just a single piece of text, then this exception is triggered. So this may be a bug in PDFSharp?

The PDF that triggers the issue can be downloaded from here.


Solution

  • This was a bug in PDFsharp up to version 6.1.0 Preview 2.

    The bug was fixed with PDFsharp version 6.1.0 Preview 3, released today.

    The check for duplicate resource names in PDFsharp was too strict and prevented those files from opening.
    PDFsharp was published about 20 years ago and this issue had not been reported before