empira / PDFsharp

PDFsharp and MigraDoc Foundation for .NET 6 and .NET Framework
https://docs.pdfsharp.net/
Other
398 stars 91 forks source link

AddDocumentLink incompatible with named destinations generated by Chrome PDF printer when opened in Acrobat/macOS/iOS #131

Open roel-de-vries opened 3 days ago

roel-de-vries commented 3 days ago

Hi!

We have a use-case where we generate the first 90% of our PDFs through Playwright/chrome and then add the remaining data with PDFSharp.

One of the things we want to do is adding named destination links to a destination that already has been generated by chrome. Only it seems that the link generated by PDFSharp does not work in some popular PDF viewers.

For example: Adobe Acrobat, macOS preview tool and iOS preview tool

Reporting an Issue Here

Expected Behavior

The link actually working/referencing to the correct destination.

Actual Behavior

The link works when the PDF is opened in a browser. It does nothing in, for example, Acrobat.

Steps to Reproduce the Behavior

Example code: PdfTesting.zip

In the project is a PDF.pdf file. This is the file generated by just a chrome desktop print-to-pdf action. It contains two pages. Page one contains a link that references to the paragraph on page 2.

When the app is ran, it generates a HelloWorld.pdf. This PDF contains three pages, one and three being the same as PDF.pdf. Page 2 now contains a simple red 'button' that also should reference the same paragraph on the page three.

Again, the link works fine in any browser. But when openend in Acrobat or when using the macOS/iOS built-in preview tool, the link stops working.

roel-de-vries commented 3 days ago

It looks like the PDF AnnotationLink is generated differently between Chrome and PDFSharp.

Chrome:

<<
  /Type /Annot
  /Subtype /Link
  /F 4
  /Border [
    0
    0
    0
  ]
  /Rect [
    58.5
    779.66998
    537.75
    790.91998
  ]
  /Dest /testing
>>

PDFSharp:

<<
  /Type /Annot
  /NM 269e1cfa-d78d-441f-8018-b6a5937cd93a
  /M D:20240703160544+02'00'
  /Subtype /Link
  /Rect [
    0
    0
    200
    200
  ]
  /BS <<
    /Type /Border
    /W 0
  >>
  /Border [
    0
    0
    0
  ]
  /A <<
    /Type /Action
    /S /GoTo
    /D testing
  >>
>>

It looks like it has some kind of sub-type Action? Where chrome specifies the destination as /Dest testing and PDFSharp as /D testing.

I lack the PDF-spec knowledge, but that was the only thing I could find that could maybe explain the behaviour.