summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps
diff options
context:
space:
mode:
Diffstat (limited to 'Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps')
-rw-r--r--Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps203
1 files changed, 140 insertions, 63 deletions
diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps
index 6ee8f7e7497..691a8bd6a91 100644
--- a/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps
+++ b/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps
@@ -1,4 +1,4 @@
-% Copyright (C) 2001-2021 Artifex Software, Inc.
+% Copyright (C) 2001-2022 Artifex Software, Inc.
% All Rights Reserved.
%
% This software is provided AS-IS with no warranty, either express or
@@ -366,12 +366,21 @@ drawopdict begin
/q { q } executeonly def
/Q { Q } executeonly def
% Graphics state setting
- /cm { //cmmatrix astore
+ /cm {
+ //cmmatrix astore
+ % If inside a BT/ET block, we need to undo the text matrix, then apply
+ % the cm, then re-apply the text matrix :-( Of course the spec says
+ % this isn't even legal.
+ currentdict /TextSaveMatrix .knownget {
+ pop
+ unsettextmatrix
+ } if
.getpath
exch concat
newpath { exec } forall
% If inside a BT/ET block, we need to update the TextSaveMatrix
currentdict /TextSaveMatrix .knownget {
+ settextmatrix
//cmmatrix exch dup concatmatrix pop
} if
% And if we ha\ve done a gsave inside a text block, we need to update
@@ -1198,41 +1207,90 @@ currentdict end readonly def
%% finished running the PaintProc.
/.actual_pdfpaintproc { % <patdict> <resdict> .pdfpaintproc -
- PDFDEBUG { //pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Begin PaintProc) print dup === flush } if } if
- PDFfile fileposition 3 1 roll
- q
- 1 index /PaintType oget 1 eq {
- % For colored patterns, set default fill and stroke colors.
- 0 g 0 G
- } {
- % For uncolored patterns, we have to unbind the current
- % color and color space before running the PaintProc.
- % Not true since moving the ExtGState parameters into the gstate.
- % //null sc1 //null SC1
+ % Check the object number of the pattern, from the pattern dictionary. Somehow
+ % there is a means to get here with no object number set, I have no idea how
+ % but this solves the immediate problem. Hopefully good enough until we drop
+ % this code. Fixes bug #704487 which is recursion caused by a pattern
+ % referenced via resolving a name from a Page as it is not defined in the Form
+ % which uses it.
+ 1 index /.gs.pdfobj# known {
+ 1 index /.gs.pdfobj# get
+ }
+ {
+ 0
} ifelse
+ 3 1 roll
+ NestedPatterns 3 index known 3 index 0 ne and
+ {
+ PDFSTOPONERROR not {
+ ( **** Error: Attempting to run a Pattern while already executing that Pattern.\n Ignoring this pattern, output may be incorrect.\n) pdfformaterror
+ pop pop pop
+ }
+ {
+ /PaintProc cvx /circular_reference signalerror
+ } ifelse
+ }
+ {
+ % Store the currnet object number in the dictionary just so we can find it later.
+ NestedPatterns 3 index null put
+ PDFDEBUG { //pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Begin PaintProc) print dup === flush } if } if
+ PDFfile fileposition 3 1 roll
+ q
+ 1 index /PaintType oget 1 eq {
+ % For colored patterns, set default fill and stroke colors.
+ 0 g 0 G
+ } {
+ % For uncolored patterns, we have to unbind the current
+ % color and color space before running the PaintProc.
+ % Not true since moving the ExtGState parameters into the gstate.
+ % //null sc1 //null SC1
+ } ifelse
- % Save old values on opstack, set pdfemptycount to new value.
- pdfemptycount countdictstack mark
+ % Save old values on opstack, set pdfemptycount to new value.
+ pdfemptycount countdictstack mark
- %% We can't simply 'def' into the dictionary saved by 'q' above, we need to
- %% call gput to copy it and store inside it. Stupid or what....
- /pdfemptycount count 3 sub gput 5 3 roll
- %
- % Stack: ... <old emptycount> <dictcount> mark <patdict> <resdict>
- % |
- % New empty count points here -----------+
+ %% We can't simply 'def' into the dictionary saved by 'q' above, we need to
+ %% call gput to copy it and store inside it. Stupid or what....
+ /pdfemptycount count 3 sub gput 5 3 roll
+ %
+ % Stack: ... <old emptycount> <dictcount> mark <patdict> <resdict>
+ % |
+ % New empty count points here -----------+
- exch //false resolvestream pdfopdict .pdfruncontext
- cleartomark
+ exch //false resolvestream pdfopdict .pdfruncontext
+ cleartomark
- //false
- { countdictstack
- 2 index le { exit } if
- currentdict /n known not or
- currentdict /n known currentdict /self known or{
- Q
- }{
- (\n **** Error: File has unbalanced q/Q operators \(too many Q's\)\n Output may be incorrect.\n)
+ //false
+ { countdictstack
+ 2 index le { exit } if
+ currentdict /n known not or
+ currentdict /n known currentdict /self known or{
+ Q
+ }{
+ (\n **** Error: File has unbalanced q/Q operators \(too many Q's\)\n Output may be incorrect.\n)
+ //pdfdict /.Qqwarning_issued .knownget
+ {
+ {
+ pop
+ }
+ {
+ currentglobal //pdfdict gcheck .setglobal
+ //pdfdict /.Qqwarning_issued //true .forceput
+ .setglobal
+ pdfformaterror
+ } executeonly ifelse
+ } executeonly
+ {
+ currentglobal //pdfdict gcheck .setglobal
+ //pdfdict /.Qqwarning_issued //true .forceput
+ .setglobal
+ pdfformaterror
+ } executeonly ifelse
+ end
+ } executeonly ifelse
+ } executeonly loop
+ {
+ (\n **** Error: File has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n)
//pdfdict /.Qqwarning_issued .knownget
{
{
@@ -1251,41 +1309,26 @@ currentdict end readonly def
.setglobal
pdfformaterror
} executeonly ifelse
- end
- } executeonly ifelse
- } executeonly loop
- {
- (\n **** Error: File has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n)
- //pdfdict /.Qqwarning_issued .knownget
- {
- {
- pop
- }
- {
- currentglobal //pdfdict gcheck .setglobal
- //pdfdict /.Qqwarning_issued //true .forceput
- .setglobal
- pdfformaterror
- } executeonly ifelse
- } executeonly
- {
- currentglobal //pdfdict gcheck .setglobal
- //pdfdict /.Qqwarning_issued //true .forceput
- .setglobal
- pdfformaterror
- } executeonly ifelse
- } executeonly if
- pop
+ } executeonly if
+ pop
- % restore pdfemptycount
- /pdfemptycount exch def
+ % restore pdfemptycount
+ /pdfemptycount exch def
- Q
- PDFDEBUG { //pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%End PaintProc) print dup === flush } if } if
- PDFfile exch setfileposition
+ Q
+ PDFDEBUG { //pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%End PaintProc) print dup === flush } if } if
+ PDFfile exch setfileposition
+ NestedPatterns exch undef
+ }ifelse
} bind executeonly odef
/.pdfpaintproc {
+ % Copy the pattern dictionary, we need it to rewind the /File if it is a file
+ % rather than a string, after we've run .actual_pdfpaintproc. If we don't reset
+ % the file position then if we try to run the PaintProc again we will already be
+ % at EOF and nothing will be executed.
+ 1 index 3 1 roll
+
%% Get the /m from pdfopdict (must be present)
%% and check its a packedarray
pdfopdict /m get dup type /packedarraytype eq {
@@ -1307,13 +1350,28 @@ currentdict end readonly def
} ifelse
%% rearrange the operands, move the boolean to the back
3 1 roll
- %% Uncopnditionally use the normal marking ops
+ %% Unconditionally use the normal marking ops
switch_to_normal_marking_ops
.actual_pdfpaintproc
%% If we were in a text block, restore the text marking ops.
{
switch_to_text_marking_ops
} if
+
+ % If the pattern dictionary has a /File (it should always but let's be safe)
+ % *and* the /File is a file object, not a string, then we need to set the
+ % position of that file (it's a subfiledecode filter) back to 0 so we can
+ % run the PaintProc again, should we need to.
+ % cf bug #704388
+ /File .knownget {
+ dup type /filetype eq
+ {
+ 0 setfileposition
+ }
+ {
+ pop
+ } ifelse
+ } if
}bind executeonly odef
/resolvepattern { % <patternstreamdict> resolvepattern <patterndict>
@@ -1352,6 +1410,25 @@ currentdict end readonly def
] cvx put
dup /BBox 2 copy knownoget { normrect FixPatternBBox put } { pop pop } ifelse
dup /.pattern_uses_transparency 1 index patternusestransparency put
+
+ % Regardless of whether we are using transparency, if we are doing Overprint
+ % simulation we still need to have the pattern code push the pdf14 compositor.
+ % We consider we are doing overprint simulation if:
+ % The current page device has /Overprint set to /simulate
+ % The current page device does NOT contain PageSpotColors (spot-capable devices can overprint)
+ % The current page device has a /PageUsesOverprint key (set by the interpreter) and it is set to true
+ % If all these conditions are true then we set /.pattern_uses_transparency, otherwise we leave it
+ % untouched as set above.
+ %
+ currentpagedevice dup
+ /Overprint get /simulate eq
+ 1 index /PageSpotColors known not and
+ exch /PageUsesOverprint .knownget not { //false } if
+ and
+ {
+ dup /.pattern_uses_transparency //true put
+ } if
+
PDFDEBUG { //pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Pattern: ) print dup === flush } if } if
} bind executeonly def