diff options
author | Ken Sharp <ken.sharp@artifex.com> | 2022-05-31 11:42:31 +0100 |
---|---|---|
committer | Ken Sharp <ken.sharp@artifex.com> | 2022-05-31 11:42:42 +0100 |
commit | e4fef6cf2181283849322c244b953d8c1d42ca4d (patch) | |
tree | 447cf237cfebb271f6118a193b948853ba67f135 /Resource | |
parent | a74ec378076af5059773e7e7b1c73b58b3e21714 (diff) | |
download | ghostpdl-e4fef6cf2181283849322c244b953d8c1d42ca4d.tar.gz |
GhostPDF - Handle Outlines in multiple input files with pdfwrite
Bug #705218 "table of contents/bookmarks wrong after merging PDF files"
Part 2 of 2 for this bug.
The pdfwrite device is capable of processing pdfmarks to produce a
variety of effects in the output. In this case we can add Link
annotations and Outlines to a PDF file. When the PDF interpreter
supports reading these from an input file we also write them to the
output file using (effectively) pdfmark operationjs.
The problem is that when we have multiple input files and the Dest of
a Link annotation or Outline is a page, that page refers to the page
number in the original file (eg 1). That won't be the correct page
number in the output file because it already contains the pages from
any previous files.
So what we need to do is offset the page number of the destination by
the number of pages already in the output. That's what this commit does;
for Ghostscript processing we store the number of pages in the device
and update at the end of each file by the number of pages in that file.
We send the number of pages to the (newly created) interpreter at the
start of every file in the dictionary argument we supply to .PDFInit.
For GhostPDF it is simpler because we handle all the files, we just
update the counter in the PDF context by the number of pages processed
in the file we have just completed.
We simply add the offset to the page number when creating the Dest
pdfmark.
This commit also extends the named destination processing to handle
name trees with more than a single node by recursively processing the
Kids array in each node. We also use the Limits to more quickly
determine if a node contains our target, rather than checking each
entry in the Names array for a match.
Diffstat (limited to 'Resource')
-rw-r--r-- | Resource/Init/pdf_main.ps | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps index 28e1e8268..8c37eba1c 100644 --- a/Resource/Init/pdf_main.ps +++ b/Resource/Init/pdf_main.ps @@ -792,6 +792,11 @@ systemdict /NEWPDF known not {/NEWPDF //true def} if { pop } ifelse } forall + % This isn't a command line parameter, we track it internally, but we need to + % send it to the interpreter. It is used to 'offset' the page Dest for Link + % annotations and Outlines by the numebr of pages processed so far. + /PageCount CumulativePageCount def + currentdict end } bind executeonly def @@ -997,6 +1002,8 @@ currentdict /PDFSwitches undef /pdfdict 10 dict def pdfdict begin + currentpagedevice /PageCount get + /CumulativePageCount exch def % This is for the benefit of pdf2dsc which assumes it will be present /Trailer << >> def /PDFSave save def @@ -1121,9 +1128,23 @@ currentdict /PDFSwitches undef /newpdf_runpdfend { + % Get the accumulated count of pages processed so far + % and the number of pages in this file. Do this before + % we close the file and restore the state. Save the values + % on the stack. + pdfpagecount + CumulativePageCount + pdfclose PDFSave restore + end % pdfdict + + % add the number of pages in this file to the accumulated count, + % and store that in the device for later reuse. This allows us to + % add the number of pages already in the output to the 'Dest' of + % Outlines and Link annotations. + add <</PageCount 3 -1 roll >> setpagedevice } bind def /newpdf_pdfopen |