From 085bde903b9e684c3c1160e4df912bea9a660997 Mon Sep 17 00:00:00 2001 From: Sam James Date: Tue, 29 Mar 2022 10:27:10 +0100 Subject: Import Ghostscript 9.56.0 Signed-off-by: Sam James --- Resource/Init/Fontmap.GS | 6 +- Resource/Init/cidfmap | 7 +- Resource/Init/gs_dps1.ps | 2 +- Resource/Init/gs_fonts.ps | 7 +- Resource/Init/gs_init.ps | 3 +- Resource/Init/gs_pdfwr.ps | 34 ++++++-- Resource/Init/gs_res.ps | 9 -- Resource/Init/pdf_base.ps | 26 ++++-- Resource/Init/pdf_draw.ps | 203 ++++++++++++++++++++++++++++++++-------------- Resource/Init/pdf_font.ps | 27 +++++- Resource/Init/pdf_main.ps | 156 +++++++++++++++++++++++++++-------- Resource/Init/pdf_ops.ps | 16 +++- 12 files changed, 361 insertions(+), 135 deletions(-) (limited to 'Resource') diff --git a/Resource/Init/Fontmap.GS b/Resource/Init/Fontmap.GS index b6fce711..65598343 100644 --- a/Resource/Init/Fontmap.GS +++ b/Resource/Init/Fontmap.GS @@ -82,7 +82,11 @@ % as well as with PostScript interpreters; .gsf fonts are compatible with % PostScript interpreters, but not with ATM or similar programs. -% +% NOTE: (as of 9.56.0) The use of Postscript operators in the cidfmap file is now deprecated, for +% compatibility with (and security of) the PDF interpreter implemented in C (rather than Postscript). +% Thus operations such as "getenv", "cvn" and ".concatstrings" are no longer supported. + +% % % Fonts contributed by: % URW++ Design and Development Incorporated diff --git a/Resource/Init/cidfmap b/Resource/Init/cidfmap index bed221ac..df9b6250 100644 --- a/Resource/Init/cidfmap +++ b/Resource/Init/cidfmap @@ -36,10 +36,11 @@ % % /ShinGo-Bold /HeiseiKakuGo-W5 ; % /Ryumin-Medium << /FileType /TrueType /Path (H:/AuxFiles/Fonts/BATANG.TTC) /SubfontID 3 /CSI [(Japan1) 2] >> ; -% /Ryumin-Medium << /FileType /TrueType /Path (windir) getenv not {(c:/windows)}if (/Fonts/BATANG.TTC)concatstrings /SubfontID 3 /CSI [(Japan1) 2] >> ; +% /Ryumin-Medium << /FileType /TrueType /Path (c:/windows/Fonts/BATANG.TTC) /SubfontID 3 /CSI [(Japan1) 2] >> ; % -% NOTE: getenv returns a boolean to indicate success of or failure, as well as the value on success. In the example, it uses this -% to include a default value should getenv fail. +% NOTE: (as of 9.56.0) The use of Postscript operators in the cidfmap file is now deprecated, for compatibility +% with (and security of) the PDF interpreter implemented in C (rather than Postscript). Thus operations such +% as "getenv", "cvn" and ".concatstrings" are no longer supported. % % (Century Gothic) << /FileType /TrueType /Path (/usr/share/fonts/truetype/fonts-japanese-gothic.ttf) /CSI [(Identity) 1] >> ; % diff --git a/Resource/Init/gs_dps1.ps b/Resource/Init/gs_dps1.ps index ba5b9b54..50d9bfb7 100644 --- a/Resource/Init/gs_dps1.ps +++ b/Resource/Init/gs_dps1.ps @@ -95,7 +95,7 @@ level2dict begin if } ifelse pop - } odef + } .bind odef % If we load a font into global VM within an inner save, the restore % will delete it from FontDirectory but not from SharedFontDirectory. diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps index f1e26b09..aaee616f 100644 --- a/Resource/Init/gs_fonts.ps +++ b/Resource/Init/gs_fonts.ps @@ -429,6 +429,11 @@ FONTPATH %END FONTPATH +/FONTMAP where +{ + dup /FONTMAP get /FONTMAP exch [ exch //.pathlist exec] put +} if + % Try to enumerate native fonts registered with the os % and add them to the fontmap. This relies on a custom % operator which calls platform-specific C code. It @@ -1315,7 +1320,7 @@ FAKEFONTS { exch } if pop def % don't bind, .current/setglobal get redefined /.loadinitialfonts { NOFONTMAP not { /FONTMAP where - { pop [ FONTMAP //.pathlist exec] + { pop FONTMAP { dup VMDEBUG findlibfile { exch pop //.loadFontmap exec } { /undefinedfilename signalerror } diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps index e3d65eca..3bf729d7 100644 --- a/Resource/Init/gs_init.ps +++ b/Resource/Init/gs_init.ps @@ -34,7 +34,7 @@ % Interpreter library version number % NOTE: the interpreter code requires that the first non-comment token % in this file be an integer, and that it match the compiled-in version! -9550 +9560 % Check the interpreter revision. dup revision ne @@ -2464,7 +2464,6 @@ currentdict /.locksafeglobal .undef /.init_otto_font_file /.composefontdict /.type1build - /.origdefinefont /.origundefinefont /.origfindfont /.buildnativefontmap /.completefont /.definefakefonts diff --git a/Resource/Init/gs_pdfwr.ps b/Resource/Init/gs_pdfwr.ps index ef468522..7945a322 100644 --- a/Resource/Init/gs_pdfwr.ps +++ b/Resource/Init/gs_pdfwr.ps @@ -691,13 +691,33 @@ currentdict /.pdf_hook_DSC_Creator undef pop 3000 % priority { - currentglobal //true setglobal - 2 dict dup .initialize_dsc_parser readonly - currentuserparams /ProcessDSCComment get - 1 array astore % in case the value is executable - //.pdfdsc /exec load 4 array astore cvx readonly - << /ProcessDSCComment 3 -1 roll >> setuserparams - setglobal + % When running gpdl, due to the way gpdl has to do job encapsulation + % the scheduled initialisation procedures get run at the start of each + % job. Because this patches the existing procedure, it could end up + % patching itself, so the procedure got larger/deeper with each job. + % Eventually, copying the user params (see /.setuserparams2 in gs_lev2.ps) + % would end up overflowing the exec stack. + % So, as part of the patching, we push and pop a sacrificial name object + % at the start of the executable array and before patching, we check that + % first element, and if it is that name, we skip the patching + currentuserparams /ProcessDSCComment .knownget + { + dup type /arraytype eq + { + 0 get /.pdf_hook_DSC_Creator eq + { //false } { //true } ifelse + } { //true } ifelse + } { //true } ifelse + + { + currentglobal //true setglobal + 2 dict dup .initialize_dsc_parser readonly + currentuserparams /ProcessDSCComment get + 1 array astore % in case the value is executable + /.pdf_hook_DSC_Creator /pop load 4 2 roll //.pdfdsc /exec load 6 array astore cvx readonly + << /ProcessDSCComment 3 -1 roll >> setuserparams + setglobal + } if } bind .schedule_init } if diff --git a/Resource/Init/gs_res.ps b/Resource/Init/gs_res.ps index c531b366..7316e32e 100644 --- a/Resource/Init/gs_res.ps +++ b/Resource/Init/gs_res.ps @@ -1054,15 +1054,6 @@ currentdict /.fontstatusaux .undef //.definefontmap exec } bind def -% Make sure the old definitions are still in systemdict so that -% they will get bound properly. -% NOTE: Mystery code... I can't just delete this, but don't understand why. -% Instead we will undef these three operators in gs_init.ps after all the initialization is done. - systemdict begin - /.origdefinefont /definefont load def - /.origundefinefont /undefinefont load def - /.origfindfont /findfont load def -end /definefont { { /Font defineresource } stopped { /definefont cvx $error /errorname get signalerror diff --git a/Resource/Init/pdf_base.ps b/Resource/Init/pdf_base.ps index 2453b6bc..87b9650d 100644 --- a/Resource/Init/pdf_base.ps +++ b/Resource/Init/pdf_base.ps @@ -1401,15 +1401,23 @@ currentdict /pdf_rules_dict undef } bind executeonly def /.leafget { % .leafget - dup length 2 eq { - dup 0 get 2 index eq { 1 oget } { pop //null } ifelse - exch pop - } { - dup length -1 bitshift -2 and 2 copy oget - % Stack: key pairs mid pairs[mid] - 3 index gt { 0 exch } { 1 index length 1 index sub } ifelse - getinterval .leafget - } ifelse + null % [pairs] null + 0 2 3 index length 1 sub % [pairs] null 0 2 length([pairs]) + { % [pairs] null index + 2 index % [pairs] null index [pairs] + exch % [pairs] null [pairs] index + 2 getinterval % [pairs] null [ ] + dup 0 get % [pairs] null [ ] + 4 index % [pairs] null [ ] + eq + { % [pairs] null [ ] + exch pop 1 oget exit % [pairs] + } { + pop % [pairs] null + }ifelse + } for + % [pairs] + 3 1 roll pop pop % } bind executeonly def % The following variants return tree entry whose key is closest but diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps index 6ee8f7e7..691a8bd6 100644 --- a/Resource/Init/pdf_draw.ps +++ b/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 { % .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: ... mark - % | - % 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: ... mark + % | + % 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 { % resolvepattern @@ -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 diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps index b42cd4cf..1be2871b 100644 --- a/Resource/Init/pdf_font.ps +++ b/Resource/Init/pdf_font.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 @@ -1622,7 +1622,6 @@ currentdict end readonly def % Following Acrobat we ignore everything outside % begincodespacerange .. endcmap. /read_CMap_stream { % read_CMap - dup 0 (begincodespacerange) /SubFileDecode filter flushfile //CMap_read_dict begin /CIDInit /ProcSet findresource begin 12 dict begin @@ -1641,7 +1640,29 @@ currentdict end readonly def dup //null eq { pop } { /CIDSystemInfo exch def } ifelse /CMapType 1 def /.last_CMap_def currentdict def % establish binding - mark exch % emulate 'begincodespacerange' + + % The stream may not be seekable, push a ReusableStream to make it seekable. + /ReusableStreamDecode filter + + % Try to skip past the 'header' portion of the PDF file to the body + % If the CMap doesn't have a begincodespacerange (eg it uses /UseCMap) + % then this will leave us at EOF. + dup 0 (begincodespacerange) /SubFileDecode filter flushfile + % See if we have anything left in the file + dup bytesavailable 0 eq + { + % We discarded all the file contents, so there was no begincodespacerange + % Rewind the file to the beginning + dup 0 setfileposition + % And try again, this time only discarding to the 'begincmap' + dup 0 (begincmap) /SubFileDecode filter flushfile + } + { + % Everything worked as expected, because we have consumed the + % begincodespacerange from the file, emulate it + mark exch + } ifelse + 0 (endcmap) /SubFileDecode filter cvx /begincmap cvx exch 2 .execn currentdict /o.endmapvalue undef endcmap diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps index 038c19d1..3259c0fe 100644 --- a/Resource/Init/pdf_main.ps +++ b/Resource/Init/pdf_main.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 @@ -218,7 +218,7 @@ DingbatsEncoding pop % Redefine 'run' so it recognizes PDF files. systemdict begin -systemdict /NEWPDF known not {/NEWPDF //false def} if +systemdict /NEWPDF known not {/NEWPDF //true def} if % PostScript interface to the ghostpdf C-based interpreter % @@ -405,8 +405,7 @@ systemdict /NEWPDF known not {/NEWPDF //false def} if % Stack - box boxwidth boxheight mediawidth mediaheight % Incorporate up any offset from 0,0 - 4 index aload pop pop pop neg exch neg exch - 2 copy exch + 4 index aload pop pop pop neg exch neg translate % Now use the box and media values to calculate the required x/y scale factors @@ -419,7 +418,6 @@ systemdict /NEWPDF known not {/NEWPDF //false def} if gt {exch} if % select smallest scale factor pop % dup scale % and scale page isomorphically - pop pop } bind def /newpdf_get_media_box { % get_media_box @@ -444,32 +442,78 @@ systemdict /NEWPDF known not {/NEWPDF //false def} if ( Output may be incorrect.\n) newpdf_pdfformaterror [ 0 0 currentpagedevice /PageSize get aload pop ] //false } ifelse -%(newpdf_get_media_box end) == flush +} bind executeonly def + +% [llx lly urx ury] newpdf_check_empty_box [llx lly urx ury] true | false +% rturns true and the original array if its valid, otherwise returns false +/newpdf_check_empty_box +{ + dup type /arraytype eq + { + dup aload pop + dup 3 index eq + { + //true + } + { + 1 index 4 index eq + } ifelse + { + pop pop pop pop + ( **** Warning: File has an empty Box parameter.\n) print + ( Using the MediaBox instead.\n) print + ( Output may be incorrect.\n) print flush + pop //false + } + { + pop pop pop pop + //true + } ifelse + } + { + ( **** Warning: File has an invalid Box parameter.\n) print + ( Using the MediaBox instead.\n) print + ( Output may be incorrect.\n) print flush + pop //false + } ifelse } bind executeonly def /newpdf_get_any_box { % get_any_box -%(newpdf_get_any_box start) == flush //systemdict /UseBleedBox .knownget dup { and } if { - dup /BleedBox get { - /BleedBox exch + dup /BleedBox .knownget { + newpdf_check_empty_box + { + /BleedBox exch + } if } if } if - //systemdict /UseTrimBox .knownget dup { and } if { - dup /TrimBox get { - /TrimBox exch + dup type /arraytype ne { + //systemdict /UseTrimBox .knownget dup { and } if { + dup /TrimBox .knownget { + newpdf_check_empty_box + { + /TrimBox exch + } if + } if } if } if dup type /arraytype ne { //systemdict /UseArtBox .knownget dup { and } if { - dup /ArtBox get { - /ArtBox exch + dup /ArtBox .knownget { + newpdf_check_empty_box + { + /ArtBox exch + } if } if } if } if dup type /arraytype ne { //systemdict /UseCropBox .knownget dup { and } if { - dup /CropBox get { - /CropBox exch + dup /CropBox .knownget { + newpdf_check_empty_box + { + /CropBox exch + } if } if } if } if @@ -484,6 +528,7 @@ systemdict /NEWPDF known not {/NEWPDF //false def} if %% content when we st up the CTM, but we do need to make sure that we clamp %% the BoundingBox, and that means we need to take direcitonality into account... + aload pop 6 -1 roll newpdf_get_media_box { % /SomeBox x0 y0 x1 y1 [MediaBox] aload pop % /SomeBox x0 y0 x1 y1 X0 Y0 X1 Y1 @@ -556,6 +601,30 @@ systemdict /NEWPDF known not {/NEWPDF //false def} if dup dup newpdf_get_any_box % Stack: pdfpagedict pdfpagedict /BoxName [box] + % Check that the box is 'normal' and make it so if not + % Also check the array is 4 elements and if it isn't then use the + % current PageSize. The normalise arithmetic assumes the array is a 4 + % element array. + dup length 4 ne { + % Invalid size of mediabox + pop currentpagedevice /PageSize get + } { + aload 5 1 roll % array x1 y1 x2 y2 + exch % array x1 y1 y2 x2 + 4 -1 roll % array y1 y2 x2 x1 + 2 copy gt { + exch % array y1 y2 xmin xmax + } if + 4 -2 roll % array xmin xmax y1 y2 + 2 copy gt { + exch % array xmin xmax ymin ymax + } if + 4 1 roll + exch 4 -1 roll + 5 -1 roll + astore + } ifelse + //systemdict /PDFFitPage known { NewPDF_FitPage } { @@ -688,7 +757,9 @@ systemdict /NEWPDF known not {/NEWPDF //false def} if } { pop } ifelse - } if + } { + pop + }ifelse pop } bind executeonly def @@ -704,10 +775,11 @@ systemdict /NEWPDF known not {/NEWPDF //false def} if /newpdf_gather_parameters { 10 dict begin - /PDFSwitches [ /PDFPassword /PDFDEBUG /PDFSTOPONERROR /PDFSTOPONWARNING /NOTRANSPARENCY /FirstPage /LastPage - /NOCIDFALLBACK /NO_PDFMARK_OUTLINES /NO_PDFMARK_DESTS /PDFFitPage /Printed + /PDFSwitches [ /QUIET /PDFPassword /PDFDEBUG /PDFSTOPONERROR /PDFSTOPONWARNING /NOTRANSPARENCY /FirstPage /LastPage + /PDFNOCIDFALLBACK /NO_PDFMARK_OUTLINES /NO_PDFMARK_DESTS /PDFFitPage /Printed /UsePDFX3Profile /UseBleedBox /UseCropBox /UseArtBox /UseTrimBox /ShowAcroForm /ShowAnnots /PreserveAnnots - /NoUserUnit /RENDERTTNOTDEF /DOPDFMARKS /PDFINFO /SHOWANNOTTYPES /PRESERVEANNOTTYPES] def + /NoUserUnit /RENDERTTNOTDEF /DOPDFMARKS /PDFINFO /SHOWANNOTTYPES /PRESERVEANNOTTYPES + /CIDSubstPath /CIDSubstFont /IgnoreToUnicode /NONATIVEFONTMAP ] def 0 1 PDFSwitches length 1 sub { PDFSwitches exch get dup where { @@ -935,8 +1007,8 @@ systemdict /NEWPDF known not {/NEWPDF //false def} if % These are also for the benefit of pdf2dsc, which assumes they % are available. - /knownoget {2 copy known {get //true}{pop //false}ifelse} bind def - /pget {2 copy known {get //true}{pop //false}ifelse}bind def + /knownoget {2 copy known {get //true}{pop pop //false}ifelse} bind def + /pget {2 copy known {get //true}{pop pop //false}ifelse}bind def newpdf_gather_parameters {.PDFInit} stopped @@ -986,7 +1058,11 @@ systemdict /NEWPDF known not {/NEWPDF //false def} if ( **** Error: Page drawing error occured.\n) newpdf_pdfformaterror ( Output may be incorrect.\n) newpdf_pdfformaterror } if - showpage + {showpage} stopped + { + ( **** Error: Page drawing error occured.\n) newpdf_pdfformaterror + ( Could not draw this page at all, page will be missing in the output.\n) newpdf_pdfformaterror + } if grestore } bind def @@ -1053,7 +1129,6 @@ systemdict /NEWPDF known not {/NEWPDF //false def} if {//true} ifelse { - QUIET not { (Page ) print dup //== exec flush } if dup pdfgetpage dup //null ne { exch 1 index @@ -3567,11 +3642,9 @@ currentdict /PDF2PS_matrix_key undef % the pages resources. It may be high if a spot color is in a resource but % is not actually used on the page. currentpagedevice /PageSpotColors known { - /PageSpotColors 2 index countspotcolors - userdict /PageSpotColors 2 index put - def + /PageSpotColors 2 index countspotcolors def + /SeparationColorNames userdict 1 index get def } if - % If the user told us to use a named OutputIntent systemdict /UseOutputIntent .knownget { cvn @@ -3640,7 +3713,7 @@ currentdict /PDF2PS_matrix_key undef % Overprint is /enable, so the device might need the overprint compositor % if it does not support spot colors, thus check if overprint is used so % overprint simulation can be done with the pdf14 compositor - 1 index countspotcolors userdict exch /PageSpotColors exch put % save it in a known place + 1 index countspotcolors pop 1 index pageusesoverprint 1 index /ProcessColorModel get /DeviceCMYK eq { PageSpotColors 0 gt % count of colorants NOT including CMYK @@ -3949,9 +4022,11 @@ currentdict /PDF2PS_matrix_key undef not and //systemdict /PreserveAnnots .knownget not {//true} if and { - mark exch {preserveannot} PDFSTOPONERROR {exec}{stopped {(Error: Ignoring invalid annotation, output may be incorrect.\n) pdfformaterror} if} ifelse {cleartomark} stopped pop + mark exch {preserveannot} PDFSTOPONERROR {exec}{stopped {(Error: Ignoring invalid annotation, output may be incorrect.\n) pdfformaterror} if} ifelse {cleartomark} stopped + {(Error: Failed to clean up after annotation, output may be incorrect.\n) pdfformaterror}if }{ - mark exch {drawannot} PDFSTOPONERROR {exec}{stopped {(Error: Ignoring invalid annotation, output may be incorrect.\n) pdfformaterror} if} ifelse {cleartomark} stopped pop + mark exch {drawannot} PDFSTOPONERROR {exec}{stopped {(Error: Ignoring invalid annotation, output may be incorrect.\n) pdfformaterror} if} ifelse {cleartomark} stopped + {(Error: Failed to clean up after annotation, output may be incorrect.\n) pdfformaterror}if } ifelse } { pop @@ -4497,11 +4572,22 @@ currentdict /PDF2PS_matrix_key undef % Note: This count does not include Cyan, Magenta, Yellow, or Black /countspotcolors { % countspotcolors pagespotcolors % Get dict with all spot colors - dup length % spot color dict length % Remove CMYK from the spot color count. [ /Cyan /Magenta /Yellow /Black ] - { 2 index exch known { 1 sub } if } forall - exch pop % Remove spot color dict + { + dup 2 index exch known { + 1 index exch undef + } { + pop + } ifelse + } forall + dup length dup + userdict exch /PageSpotColors exch put % save it in a known place + exch + userdict /SeparationColorNames 2 index + [ exch { pop } forall ] + put % and save the SpotColorNames array in a known place + pop % done with spot color dict } bind executeonly def % ------ ColorSpace substitution support ------ % @@ -4834,6 +4920,8 @@ currentdict /PDF2PS_matrix_key undef pop }bind readonly def +/NestedPatterns <<>> def + end % pdfdict diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps index 27c20680..a00356c7 100644 --- a/Resource/Init/pdf_ops.ps +++ b/Resource/Init/pdf_ops.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 @@ -716,7 +716,8 @@ end //false } ifelse .currentSMask //null ne or { % push a group for OP or SMask - mark /Subtype /Group /Isolated .currentSMask //null ne .dicttomark + % It should only be isolated if there is a softmask and the blend mode is not normal (or compatible) + mark /Subtype /Group /Isolated .currentSMask //null ne .currentblendmode /Normal ne and .currentblendmode /Compatible ne and .dicttomark 2 index aload pop % pathbbox .begintransparencygroup % After group pushed, set alphas and blendmode @@ -1026,6 +1027,17 @@ end readonly def translate } if } bind executeonly def +/unsettextmatrix { + .currenttextrise 0 ne { + 0 .currenttextrise neg translate + } if + .currenttexthscaling 1 ne { + 1 .currenttexthscaling div 1 scale + } if + matrix currentmatrix + matrix .currenttextmatrix matrix invertmatrix concat setmatrix +} bind executeonly def + /settextstate { % The text state can be set even outside BT/ET. currentdict /TextSaveMatrix known { -- cgit v1.2.3-65-gdbad