summaryrefslogtreecommitdiff
path: root/Resource
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2022-05-31 11:42:31 +0100
committerKen Sharp <ken.sharp@artifex.com>2022-05-31 11:42:42 +0100
commite4fef6cf2181283849322c244b953d8c1d42ca4d (patch)
tree447cf237cfebb271f6118a193b948853ba67f135 /Resource
parenta74ec378076af5059773e7e7b1c73b58b3e21714 (diff)
downloadghostpdl-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.ps21
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