diff options
author | Reinhard Kotucha <reinhard.kotucha@web.de> | 2019-10-16 20:19:46 +0000 |
---|---|---|
committer | Reinhard Kotucha <reinhard.kotucha@web.de> | 2019-10-16 20:19:46 +0000 |
commit | 5495dccfe2922c9db6a88df19c1ae41f9c3f363d (patch) | |
tree | 0ec95929b4ae75a0642253c266a77da5a9e3c0c5 /Master/tlpkg/tlgs/Resource/Init | |
parent | 147afe376edb627c38fd6f76cb1fcd6d1e444ee9 (diff) |
Upgrade gs-9.27 -> gs-9.50
git-svn-id: svn://tug.org/texlive/trunk@52405 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/tlpkg/tlgs/Resource/Init')
26 files changed, 1093 insertions, 665 deletions
diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_btokn.ps b/Master/tlpkg/tlgs/Resource/Init/gs_btokn.ps index 3d6de33eb76..b9add38368a 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_btokn.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_btokn.ps @@ -338,5 +338,5 @@ end /.cntobj /.writeobject /.writeobjects -] -{level2dict exch .forceundef} forall +] dup level2dict .undefinternalnames +systemdict .undefinternalnames diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_cet.ps b/Master/tlpkg/tlgs/Resource/Init/gs_cet.ps index 54f17c645d6..c168165eb1f 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_cet.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_cet.ps @@ -90,7 +90,7 @@ dup 7 -1 put { ofile } ifelse -} bind //.odef exec +} .bind //.odef exec currentdict /ofile undef % One QL job (23-12B.PS) effectively does: @@ -113,7 +113,7 @@ currentdict /ofile undef { osetfileposition } ifelse -} bind //.odef exec +} .bind //.odef exec currentdict /osetfileposition undef setglobal diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_cff.ps b/Master/tlpkg/tlgs/Resource/Init/gs_cff.ps index 125906132b7..99d214a64b6 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_cff.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_cff.ps @@ -26,9 +26,9 @@ % Augment the FONTPATH machinery so it recognizes OpenType CFF font sets. /.scanfontheaders where { - pop /.scanfontheaders [ - .scanfontheaders aload pop (OTTO*) - ] def + /.scanfontheaders [ + /.scanfontheaders .systemvar aload pop (OTTO*) + ] put } if % Load a font file that might be an OpenType CFF font set. diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_cidfm.ps b/Master/tlpkg/tlgs/Resource/Init/gs_cidfm.ps index c0237283cd8..5eb25f0042f 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_cidfm.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_cidfm.ps @@ -133,9 +133,39 @@ currentdict end def } if >> def +% <dir.../base.extn> .basename <dir> +/.splitdirname { + (/) rsearch { //true } { (\\) rsearch } ifelse + {3 -2 roll pop pop //true}{//false} ifelse +} bind def + +% <file> .addcidfmappath - +/.addcidfmpermitpath +{ + .filename + { + //.splitdirname exec + {dup def} if + } if +} bind def + /VerifyMap % <raw_map> VerifyMap - { + % This is where we insert the default fallback into the map + % checking first to see if there is a user specified alternative + dup /CIDFallBack known not{ + //DefaultCIDFallBack dup /Path get status + { + pop pop pop pop + /CIDFallBack exch 2 index 3 1 roll put + } + { + pop + }ifelse + } if + % Remove any mappings for which we cannot find the font file + dup length dict begin dup { % if we have a name1->name2 mapping, follow the "trail", @@ -163,11 +193,12 @@ currentdict end def /Path .knownget { .libfile - {closefile pop} + { + dup //.addcidfmpermitpath exec closefile pop} { {(r) file} //.internalstopped exec {pop pop 2 index exch .undef} - {closefile pop} ifelse + {dup //.addcidfmpermitpath exec closefile pop} ifelse } ifelse } {2 index exch .undef} @@ -177,19 +208,8 @@ currentdict end def } ifelse } loop } forall - - % This is where we insert the default fallback into the map - % checking first to see if there is a user specified alternative - dup /CIDFallBack known not{ - //DefaultCIDFallBack dup /Path get status - { - pop pop pop pop - /CIDFallBack exch 2 index 3 1 roll put - } - { - pop - }ifelse - } if + currentdict end + {exch pop (/) concatstrings /PermitFileReading exch .addcontrolpath} forall % Checks for vicious substitution cycles. dup length dict copy % <<map>> @@ -233,6 +253,9 @@ currentdict end def pop pop } bind def +currentdict /.splitdirname undef +currentdict /.addcidfmpermitpath undef + /PreprocessRecord % <map> <Name> <raw_record> PreprocessRecord <map> <Name> <record> <bool> { //IsMyRecord exec { diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_cidfn.ps b/Master/tlpkg/tlgs/Resource/Init/gs_cidfn.ps index 80b8008cf30..ca2a5a7ca20 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_cidfn.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_cidfn.ps @@ -423,4 +423,4 @@ dup /.CheckResource { /.checkfonttype /.loadcidfontresource /.readglyphdata -] {systemdict exch .forceundef} forall +] systemdict .undefinternalnames diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_dps2.ps b/Master/tlpkg/tlgs/Resource/Init/gs_dps2.ps index fe3ca27dd5b..619984f2fe1 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_dps2.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_dps2.ps @@ -220,21 +220,21 @@ currentdict /.fixcurrenthalftonescreen undef .UserObjects 3 .argindex 1 add 10 .max .localvmarray put } ifelse .UserObjects get 2 .argindex 2 index put pop pop -} bind odef +} .bind odef /execuserobject { % <index> execuserobject - dup type /integertype ne { % Adobe validates the argument before accessing UserObjects - CET 31-03 /execuserobject .systemvar /typecheck signalerror } if .UserObjects get 1 .argindex get exch pop exec -} bind odef +} .bind odef /undefineuserobject { % <index> undefineuserobject - dup type /integertype ne { % Adobe validates the argument before accessing UserObjects - CET 31-11 /undefineuserobject .systemvar /typecheck signalerror } if .UserObjects get 1 .argindex //null put pop -} bind odef +} .bind odef currentdict /.UserObjects undef % ------ Cache control ------ % diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_epsf.ps b/Master/tlpkg/tlgs/Resource/Init/gs_epsf.ps index b337f42856f..b28f742ef88 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_epsf.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_epsf.ps @@ -312,5 +312,4 @@ end /EPSBoundingBoxParse /EPSBoundingBoxProcess /ProcessEPSComment -] -{currentdict exch .forceundef} forall +] currentdict .undefinternalnames diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_fapi.ps b/Master/tlpkg/tlgs/Resource/Init/gs_fapi.ps index 53b744604fa..1ca3dff7b52 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_fapi.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_fapi.ps @@ -372,7 +372,7 @@ bind def { (\nFAPIhook ) print 1 index = flush } //FAPI_hook_debug exec dup /FAPI known { { //PrintFontRef exec ( is mapped to FAPI=) print dup /FAPI get = flush } //FAPI_hook_debug exec - //true //.FAPIrebuildfont //ChooseDecoding exec + //true .FAPIrebuildfont //ChooseDecoding exec } { dup /PathLoad known dup { { (PathLoad known for the font ) print //PrintFontRef exec (.\n) print flush} //FAPI_hook_debug exec @@ -403,9 +403,9 @@ bind def } ifelse { { (Trying to render the font ) print //PrintFontRef exec ( with FAPI...\n) print flush } //FAPI_hook_debug exec - //.FAPIpassfont { + .FAPIpassfont { { //PrintFontRef exec ( is being rendered with FAPI=) print dup /FAPI get = flush } //FAPI_hook_debug exec - //false //.FAPIrebuildfont //ChooseDecoding exec + //false .FAPIrebuildfont //ChooseDecoding exec } { { (Can't render ) print //PrintFontRef exec ( with FAPI, will do with native GS renderer.\n) print flush } //FAPI_hook_warn exec } ifelse @@ -429,7 +429,7 @@ bind def % ------------------ Redefine .buildfont* with FAPI : ----------------------- /.buildfont1 -{ //.buildfont1 exec exec //FAPIhook exec +{ //.buildfont1 exec //FAPIhook exec } bind % 'odef' is below. /.buildfont2 @@ -456,7 +456,7 @@ end % the temporary dictionary for local binding. odef odef odef odef odef odef % Undef these, not needed outside this file -[ /.FAPIavailable /.FAPIpassfont /.FAPIrebuildfont ] {systemdict exch .forceundef} forall +[ /.FAPIavailable /.FAPIpassfont /.FAPIrebuildfont ] systemdict .undefinternalnames .setlanguagelevel diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_fntem.ps b/Master/tlpkg/tlgs/Resource/Init/gs_fntem.ps index 196c8641418..66432e11e93 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_fntem.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_fntem.ps @@ -270,7 +270,8 @@ currentdict end def .dicttomark def /ChooseDecoding % <font> ChooseDecoding <font> -{ { % A loop for 'exit' context. +{ + { % A loop for 'exit' context. dup /Decoding .knownget { dup type /nametype eq { 1 index /CIDFontType known { /CIDDecoding } { /Decoding } ifelse @@ -305,6 +306,7 @@ currentdict end def { % unknown encoding, or an encoding for which we don't have a % predefined decoding, convert it to decoding : + currentglobal 3 1 roll 2 index gcheck setglobal dup length dict begin /.notdef 0 def 0 1 currentdict length 1 sub @@ -317,6 +319,7 @@ currentdict end def } for pop currentdict end + 3 -1 roll setglobal 1 index exch /Decoding exch put } if } ifelse diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_fonts.ps b/Master/tlpkg/tlgs/Resource/Init/gs_fonts.ps index c47f6e57767..8e361552bc8 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_fonts.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_fonts.ps @@ -36,7 +36,6 @@ end def .setlanguagelevel - % ------ End of editable parameters ------ % % Define the UniqueIDs and organization XUID assigned to Artifex. @@ -67,6 +66,36 @@ end def loop } bind def +% <dir.../base.extn> .basename <dir> +/.splitdirname { + (/) rsearch { //true } { (\\) rsearch } ifelse + {3 -2 roll pop pop //true}{//false} ifelse +} bind def + +% <dict> .addfontmappermitpaths +% As fontmap can contain a *lot* of individual entries +% we split off the filenames, and add directories to the +% allowed paths. +% We accumulate the paths in a dictionary, then iterate +% the dictionary adding the paths to the PermitReading +% list. This leverages the efficiency of dictionaries +% handling duplicate keys. +/.addfontmappermitpaths +{ + dup length dict begin + { + exch pop dup type /stringtype eq + {//.splitdirname exec {dup def} {pop} ifelse} + {pop} + ifelse + } forall + currentdict end + {exch pop /PermitFileReading exch .addcontrolpath}forall +} bind def + +defaultfontmap_content length 0 gt +{defaultfontmap_content .addfontmappermitpaths} if + % Load a font name -> font file name map. userdict /Fontmap .FontDirectory maxlength dict put userdict /.nativeFontmap .FontDirectory maxlength dict put @@ -76,7 +105,8 @@ userdict /.nativeFontmap .FontDirectory maxlength dict put % specification that makes later entries override earlier % ones within the same file. 50 dict exch .readFontmap - { .definefontmap } forall + dup //.addfontmappermitpaths exec + { .definefontmap } forall } bind def /.readFontmap { % <dict> <file> .readFontmap <dict> { dup token not { closefile exit } if @@ -232,6 +262,11 @@ ifelse FONTPATH length 0 eq { (%END FONTPATH) .skipeof } if /FONTPATH [ FONTPATH .pathlist ] def +FONTPATH +{ + /PermitFileReading exch .addcontrolpath +} forall + % Scan directories looking for plausible fonts. "Plausible" means that % the file begins with %!PS-AdobeFont or %!FontType1, or with \200\001 % followed by four arbitrary bytes and then either of these strings. @@ -309,7 +344,7 @@ FONTPATH length 0 eq { (%END FONTPATH) .skipeof } if /.scan1fontstring 8192 string def % BeginFont: is not per Adobe documentation, but a few fonts have it. /.scanfontheaders [(%!PS-Adobe*) (%!FontType*) (%%BeginFont:*)] def -0 //.scanfontheaders { length .max } forall 6 add % extra for PFB header +0 /.scanfontheaders .systemvar { length .max } forall 6 add % extra for PFB header /.scan1fontfirst exch string def /.scanfontdir % <dirname> .scanfontdir - { currentglobal exch //true setglobal @@ -349,7 +384,7 @@ FONTPATH length 0 eq { (%END FONTPATH) .skipeof } if { dup length 6 sub 6 exch getinterval } if % Check for font file headers. - //false //.scanfontheaders + //false /.scanfontheaders .systemvar { 2 index exch .stringmatch or } forall exch pop @@ -1003,13 +1038,25 @@ $error /SubstituteFont { } put % check <libflag> { findlibfile not - } { + } + { + //true + } ifelse + + + % if findlibfile didn't work, try just opening the file direcly. + { dup (r) { file } stopped { pop pop //true } { //false } ifelse - } ifelse { + } + { + //false + }ifelse + + { QUIET not { (Can't find \(or can't open\) font file ) print dup print (.) = flush @@ -1101,7 +1148,7 @@ $error /SubstituteFont { } put } loop % end of loop - } bind executeonly odef % must be bound and hidden for .putgstringcopy + } bind executeonly def % must be bound and hidden for .putgstringcopy % Attempt to load a font from a file. /.tryloadfont { % <fontname> .tryloadfont <font> true @@ -1111,14 +1158,14 @@ $error /SubstituteFont { } put /.genericrfn where { pop pop dup //.fonttempstring /FontResourceDir getsystemparam .genericrfn - {//false .loadfontloop} //.internalstopped exec {//false} if { + {//false //.loadfontloop exec} //.internalstopped exec {//false} if { //true } { dup //.nametostring exec - {//true .loadfontloop} //.internalstopped exec {//false} if + {//true //.loadfontloop exec} //.internalstopped exec {//false} if } ifelse } { - {//true .loadfontloop} //.internalstopped exec {//false} if + {//true //.loadfontloop exec} //.internalstopped exec {//false} if } ifelse } bind def @@ -1138,7 +1185,7 @@ $error /SubstituteFont { } put { exch pop //true //false } { % if we can't load by name check the native font map - dup .nativeFontmap exch .knownget + .nativeFontmap exch .knownget { //true //true } { //false //false } ifelse } ifelse @@ -1185,7 +1232,7 @@ $error /SubstituteFont { } put { 1 dict begin } ifelse - //true .loadfontloop + //true //.loadfontloop exec end { //true exit } if } @@ -1292,5 +1339,5 @@ FAKEFONTS { exch } if pop def % don't bind, .current/setglobal get redefined /.nametostring /.fontnamestring /.checkalias /.fontknownget /.stdsubstfont /.putgstringcopy /.definenativefontmap - /.findfontname -] {systemdict exch .forceundef} forall + /.findfontname /.addfontmappermitpaths /.splitdirname +] systemdict .undefinternalnames diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_img.ps b/Master/tlpkg/tlgs/Resource/Init/gs_img.ps index be1dc8fd298..00d79df34ac 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_img.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_img.ps @@ -734,8 +734,7 @@ if /img_check_ary /img_unbuild_ary /.is_low_resolution -] -{currentdict exch .undef} forall +] currentdict .undefinternalnames end % systemdict diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_init.ps b/Master/tlpkg/tlgs/Resource/Init/gs_init.ps index 55a785eceed..722b57c1e80 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_init.ps +++ b/Master/tlpkg/tlgs/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! -927 +950 % Check the interpreter revision. dup revision ne @@ -182,11 +182,12 @@ currentdict /DELAYSAFER known { /DELAYSAFER //true def /NOSAFER //true def } if /SAFER currentdict /NOSAFER known { //false } { - currentdict /SAFER known - currentdict /PARANOIDSAFER known or % PARANOIDSAFER is equivalent + //true } ifelse def +/OLDSAFER currentdict /OLDSAFER known def + /SAFERERRORS currentdict /NOSAFERERRORS known { @@ -333,6 +334,59 @@ DELAYBIND } .bind def } executeonly if +.currentglobal //true .setglobal +/.undefinternalnameslist 10 dict def +.setglobal + +% Under normal operation .undefinternalnames simply removes +% the keys in the array parameter from the dictionary parameter. +% Under DELAYBIND operation, we accumulate the names in dictionaries, +% stored in .undefinternalnameslist, and then .bindow calls +% .applyundefinternalnames once all binds have been applied. +% The .undefinternalnameslist dictionary is a little odd in that it +% uses the dictionary from which the keys should be undefined as the +% 'key' and then the value is a dictionary whose key/value pairs are +% both the names to be undefined. +% +% [array of names] <<dict from which to undef>> .undefinternalnames - +/.undefinternalnames +{ + DELAYBIND + { + .currentglobal //true .setglobal 3 1 roll + dup //.undefinternalnameslist exch .knownget not + { + 128 dict dup 3 1 roll + //.undefinternalnameslist 3 1 roll put + }{exch pop} ifelse + exch + { + dup 2 index 3 1 roll put + } forall + pop + .setglobal + } + { + exch + { + 1 index exch .forceundef + } executeonly forall + pop + } executeonly ifelse +} .bind executeonly def + +/.applyundefinternalnames +{ + //.undefinternalnameslist + { + { + pop + 1 index exch .forceundef + } executeonly forall + pop + } executeonly forall +} .bind executeonly def + %**************** BACKWARD COMPATIBILITY **************** /hwsizedict mark /HWSize //null .dicttomark readonly def /copyscanlines { % <device> <y> <string> copyscanlines <substr> @@ -550,7 +604,7 @@ currentdict /.execute .undef % We run the handleerror procedure using .internalstopped so that broken error handlers % won't cause nested errors (Unexpected Error conditions). /handleerror - JOBSERVER { + //systemdict /JOBSERVER get{ { /.GShandleerror .systemvar //.internalstopped exec pop } bind % always use .GShandleerror. } { { /errordict .systemvar /handleerror get //.internalstopped exec pop } bind % PLRM standard errorhandling @@ -570,7 +624,7 @@ currentdict /.execute .undef count 0 ne { (<) print count =only } if (>) print flush } bind def -/prompt { flush flushpage NOPROMPT not { //.promptmsg exec} if } bind def +/prompt { flush flushpage //systemdict /NOPROMPT get not { //.promptmsg exec} if } bind def currentdict /.promptmsg .undef /pstack { 0 1 count 3 sub { index == } for } bind def @@ -654,7 +708,7 @@ odef } odef /.confirmread { - TTYPAUSE { + //systemdict /TTYPAUSE get { (/dev/tty) (r) file dup read pop pop closefile } { .echo.mode //false echo @@ -667,11 +721,11 @@ odef } bind executeonly def /.confirm { - DISPLAYING NOPAUSE not TTYPAUSE or and { + //systemdict /DISPLAYING get //systemdict /NOPAUSE get not //systemdict /TTYPAUSE get or and { % Print a message (unless NOPAGEPROMPT or NOPROMPT is true) % and wait for the user to type something. % If the user just types a newline, flush it. - NOPAGEPROMPT NOPROMPT or { pop } { print flush } ifelse + //systemdict /NOPAGEPROMPT get //systemdict /NOPROMPT get or { pop } { print flush } ifelse //.confirmread exec } { pop @@ -711,7 +765,7 @@ odef % Code output by Adobe Illustrator relies on the fact that % `stack' is a procedure, not an operator!!! /stack { 0 1 count 3 sub { index = } for } bind def -/start { BATCH { //null 0 .quit } { executive } ifelse } def +/start { //systemdict /BATCH get { //null 0 .quit } { executive } ifelse } def /store { % Don't alter operands before completing. 1 .argindex where { 2 index 2 index put pop pop } { def } ifelse } odef @@ -941,7 +995,7 @@ currentdict /runlibfile0 .undef /.unstoppederrorhandler % <command> <errorname> .unstoppederrorhandler - { % This is the handler that gets used for recursive errors, % or errors outside the scope of a 'stopped'. - 2 copy SHORTERRORS + 2 copy //systemdict /SHORTERRORS get { (%%[ Error: ) print =only flush (; OffendingCommand: ) print =only ( ]%%) = } @@ -963,7 +1017,6 @@ currentdict /runlibfile0 .undef /.errorhandler % <command> <errorname> .errorhandler - { % Detect an internal 'stopped'. 1 .instopped { //null eq { pop pop stop } if } if - (I) //false .setdebug $error /.inerror get 1 .instopped { pop } { pop //true } ifelse { //.unstoppederrorhandler exec } if % detect error recursion @@ -1090,7 +1143,7 @@ currentdict /.unstoppederrorhandler .undef /.printerror { $error begin newerror { - /command load errorname SHORTERRORS + /command load errorname //systemdict /SHORTERRORS get { (%%[ Error: ) print =only flush (; OffendingCommand: ) print =only errorinfo dup //null eq { @@ -1409,8 +1462,8 @@ put % errordict /rangecheck /devicenames devicedict { pop } forall devicedict length packedarray def % Determine the default device. -/defaultdevice DISPLAYING - { systemdict /DEVICE .knownget +/defaultdevice //systemdict /DISPLAYING get + { //systemdict /DEVICE .knownget { devicedict 1 index known not { (Unknown device: ) print = flush /defaultdevice cvx 1 .quit @@ -1505,7 +1558,7 @@ setpacking % between 200 and 400 DPI, so we use it for lower resolutions. % Imagesetters need even higher frequency screens. //systemdict /DITHERPPI known - { DITHERPPI + { //systemdict /DITHERPPI get } { dup cvi 100 idiv 15 .min {//null 46 46 60 60 60 106 106 106 106 133 133 133 133 133 150} @@ -1546,7 +1599,7 @@ setpacking 4 -1 roll 150 ge { /setcolorscreen where { pop //systemdict /COLORSCREEN known - { COLORSCREEN } + { //systemdict /COLORSCREEN get} { 3 index } ifelse dup //false ne @@ -2162,6 +2215,43 @@ readonly def } if ] def +/.lockfileaccess { + .currentpathcontrolstate + { + //QUIET not + { + (\n **** WARNING: .lockfileaccess or .setsafe called ****\n) print + ( **** when file access controls are already active ****\n) print flush + } if + } + { + [ + //tempfilepaths (*) .generate_dir_list_templates + /FONTPATH .systemvar (*) .generate_dir_list_templates + /level2dict where { + pop + % Default resources : + [ currentsystemparams /GenericResourceDir get] (*) .generate_dir_list_templates + } if + /LIBPATH .systemvar (*) .generate_dir_list_templates + currentuserparams /ICCProfilesDir known { + [currentuserparams /ICCProfilesDir get] (*) + .generate_dir_list_templates + } if + ] {/PermitFileReading exch .addcontrolpath} forall + + [ + //tempfilepaths (*) .generate_dir_list_templates + ] {/PermitFileWriting exch .addcontrolpath} forall + + [ + //tempfilepaths (*) .generate_dir_list_templates + ] {/PermitFileControl exch .addcontrolpath} forall + + .activatepathcontrol + } ifelse +} bind def + /.locksafe_userparams { SAFETY /safe get not { << @@ -2219,15 +2309,24 @@ currentdict /tempfilepaths undef /.setsafe { - SAFETY /safe get not { - << - /PermitFileReading [ ] - /PermitFileWriting [ ] - /PermitFileControl [ ] - >> setuserparams + OLDSAFER { + SAFETY /safe get not { + << + /PermitFileReading [ ] + /PermitFileWriting [ ] + /PermitFileControl [ ] + >> setuserparams + } + if + .locksafe } - if - .locksafe + { + //.lockfileaccess exec + DELAYBIND not { + //systemdict /SAFERUndefinePostScriptOperators .knownget {exec} if + } if + } + ifelse } .bind executeonly odef %% --- End documented extensions --- @@ -2255,16 +2354,26 @@ currentdict /tempfilepaths undef % See /.locksafeglobal above. % /.setsafeglobal { - SAFETY /safe get not { - << - /PermitFileReading [ ] - /PermitFileWriting [ ] - /PermitFileControl [ ] - >> setuserparams + OLDSAFER + { + SAFETY /safe get not { + << + /PermitFileReading [ ] + /PermitFileWriting [ ] + /PermitFileControl [ ] + >> setuserparams + } + if + //.locksafeglobal exec } - if - //.locksafeglobal exec -} .bind def + { + //.lockfileaccess exec + DELAYBIND not { + //systemdict /SAFERUndefinePostScriptOperators .knownget {exec} if + } if + } + ifelse +} .bind executeonly odef % If we are running in SAFER mode, lock things down SAFER { .setsafeglobal } if @@ -2338,7 +2447,7 @@ SAFER { /.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile /.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams /.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath /.currentoutputdevice - /.type /.writecvs /.setSMask /.currentSMask /.needinput /.countexecstack /.execstack /.applypolicies + /.type /.writecvs /.setSMask /.currentSMask /.needinput /.countexecstack /.execstack /filterdict /.cidfonttypes /.colorrenderingtypes /.formtypes /.halftonetypes /.imagetypes /.imagemasktypes /.patterntypes /.shadingtypes /.wheredict /.renderingintentdict @@ -2435,15 +2544,6 @@ SAFER { //systemdict /UndefinePostScriptOperators .forceundef } .bind executeonly def % must be bound and hidden for .forceundef -% Undefine operators that are used by PDF internally. -% This list is maintained in pdf_main.ps -/UndefinePDFOperators { - .PDF_UNDEF_OPLIST - {//systemdict exch .forceundef} forall - //systemdict /.PDF_UNDEF_OPLIST .forceundef - //systemdict /UndefinePDFOperators .forceundef -} .bind def - % If we delayed binding, make it possible to do it later. /.bindnow { currentuserparams /IdiomRecognition .knownget { @@ -2456,21 +2556,24 @@ SAFER { 0 1 .delaycount 1 sub { .delaybind exch get .bind pop } for //systemdict /.delaybind {} .forceput % reclaim the space //systemdict /.bindnow .forceundef % ditto + .applyundefinternalnames put SAFER { //systemdict /SAFERUndefinePostScriptOperators get exec } if //systemdict /UndefinePostScriptOperators get exec - //systemdict /UndefinePDFOperators get exec //systemdict /.forcecopynew .forceundef % remove temptation //systemdict /.forceput .forceundef % ditto //systemdict /.undef .forceundef % ditto //systemdict /.bindoperators .forceundef //systemdict /.forceundef .forceundef % ditto + //systemdict /.undefinternalnames .forceundef + //systemdict /.applyundefinternalnames .forceundef + //systemdict /.undefinternalnameslist .forceundef currentuserparams /IdiomRecognition known { 1 dict dup /IdiomRecognition 4 -1 roll put setuserparams } if -} .bind odef +} .bind def % Turn off array packing, since some PostScript code assumes that % procedures are writable. @@ -2549,13 +2652,12 @@ DELAYBIND not { //systemdict /SAFERUndefinePostScriptOperators get exec } if //systemdict /UndefinePostScriptOperators get exec - //systemdict /UndefinePDFOperators .forceundef } if end % Clean up VM, and enable GC. Use .vmreclaim to force the GC. /vmreclaim where - { pop NOGC not { 2 .vmreclaim 0 vmreclaim } if + { pop //systemdict /NOGC get not { 2 .vmreclaim 0 vmreclaim } if } if systemdict /.vmreclaim .undef level2dict /.vmreclaim .undef @@ -2574,6 +2676,9 @@ DELAYBIND not { systemdict /.forcecopynew .undef % remove temptation systemdict /.forceput .undef % ditto systemdict /.forceundef .undef % ditto + systemdict /.undefinternalnames .undef + systemdict /.applyundefinternalnames .undef + systemdict /.undefinternalnameslist .undef } if % Can't remove this one until the last minute :-) diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_lev2.ps b/Master/tlpkg/tlgs/Resource/Init/gs_lev2.ps index 98d55fe7425..0fd4164650a 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_lev2.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_lev2.ps @@ -158,7 +158,7 @@ end { pop pop } ifelse - } forall + } executeonly forall % A context switch might have occurred during the above loop, % causing the interpreter-level parameters to be reset. % Set them again to the new values. From here on, we are safe, @@ -229,9 +229,9 @@ end { pop pop } ifelse - } + } executeonly forall pop -} .bind odef +} .bind executeonly odef % Initialize the passwords. % NOTE: the names StartJobPassword and SystemParamsPassword are known to @@ -1241,5 +1241,5 @@ end % level2dict /.setcolorrendering1 /.checkparamtype /.checksetparams -] -{level2dict exch .forceundef} forall +] dup level2dict .undefinternalnames +systemdict .undefinternalnames diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_ll3.ps b/Master/tlpkg/tlgs/Resource/Init/gs_ll3.ps index 359579f3e72..6caa93f8047 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_ll3.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_ll3.ps @@ -554,7 +554,7 @@ pssystemparams /MaxDisplayAndSourceList 160000 .forceput /.makehalftone7 /.sethalftone6 /.sethalftone10 /.sethalftone16 /.readbytestring /.bigstring ] -dup {currentdict exch .forceundef} forall -{systemdict exch .forceundef} forall +dup currentdict .undefinternalnames +systemdict .undefinternalnames end % ll3dict diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_pdfwr.ps b/Master/tlpkg/tlgs/Resource/Init/gs_pdfwr.ps index 00c19faf3c4..422e66e1a6c 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_pdfwr.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_pdfwr.ps @@ -282,6 +282,12 @@ languagelevel 2 .setlanguagelevel % The ps2pdf* scripts invoke this. /.setpdfwrite { % - .setpdfwrite - % Set a large VM threshold to reduce garbage collection. + (\n**** WARNING: The .setpdfwrite operator has been deprecated and will be removed entirely\n) print + ( in the next release of Ghostscript. The functionality of this operator has\n) print + ( been reduced to increasing the size of the VM threshold. If you believe you\n) print + ( have a real need for this then you should replace your call to .setpdfwrite\n) print + ( with:\n\n) print + ( 3000000 setvmthreshold\n\n) print currentuserparams /VMThreshold get 3000000 .max setvmthreshold } bind def @@ -652,11 +658,11 @@ currentdict /.pdfmarkparams .undef systemdict /.pdf_hooked_DSC_Creator //true .forceput } executeonly if pop - } if + } executeonly if } { pop } ifelse - } + } executeonly { pop } ifelse diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_res.ps b/Master/tlpkg/tlgs/Resource/Init/gs_res.ps index 0f8cb8f6cd1..068514bf21f 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_res.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_res.ps @@ -240,10 +240,10 @@ def % Stack: <template> <proc> <scratch> <category> proc exch pop % pop the category exec end -} bind executeonly def +} .bind executeonly def /resourceforall { % <template> <proc> <scratch> <category> resourceforall1 - //resourceforall1 exec % see above -} bind executeonly odef +} .bind executeonly odef /resourcestatus { % <key> <category> resourcestatus <status> <size> true % <key> <category> resourcestatus false { @@ -259,7 +259,7 @@ def % for error reporting. CET 23-26 /resourcestatus cvx $error /errorname get signalerror } if -} bind executeonly odef +} .bind executeonly odef /undefineresource { % <key> <category> undefineresource - 0 .argindex type /nametype ne { /undefinedresource cvx /typecheck signaloperror @@ -272,7 +272,7 @@ def % here but uses operator for the errors above. CET 23-33 /undefineresource cvx $error /errorname get signalerror } if -} bind executeonly odef +} .bind executeonly odef % Define the system parameters used for the Generic implementation of % ResourceFileName. @@ -458,7 +458,7 @@ status { { 2 copy .Instances exch exec } if .LocalInstances exch exec - } bind executeonly + } .bind executeonly % Because of some badly designed code in Adobe's CID font downloader that % makes findresource and resourcestatus deliberately inconsistent with each % other, the default FindResource must not call ResourceStatus if there is @@ -484,7 +484,7 @@ status { /findresource cvx //.undefinedresource exec } ifelse } ifelse -} bind executeonly +} .bind executeonly % Because of some badly designed code in Adobe's CID font downloader, the % definition of ResourceStatus for Generic and Font must be the same (!). % We patch around this by using an intermediate .ResourceFileStatus procedure. @@ -494,7 +494,7 @@ status { } { .ResourceFileStatus } ifelse -} bind executeonly +} .bind executeonly /.ResourceFileStatus { .ResourceFile { closefile 2 -1 //true } { pop //false } ifelse } bind executeonly @@ -555,7 +555,7 @@ status { 3 2 roll pop % args { forall } 0 get currentdict end 2 .execn begin -} bind executeonly +} .bind executeonly /ResourceFileName { % /in (scr) --> (p/c/n) exch //.rfnstring cvs % (scr) (n) @@ -587,7 +587,7 @@ status { ifelse } ifelse exch copy % (p/c/n) -} bind executeonly +} .bind executeonly % Additional entries @@ -1012,7 +1012,7 @@ currentdict /.fontstatusaux .undef /ResourceForAll { { //.scannextfontdir exec not { exit } if } loop /Generic /Category findresource /ResourceForAll get exec -} bind executeonly +} .bind executeonly /.ResourceFileStatus { .fontstatus { pop 2 -1 //true } { pop //false } ifelse } bind executeonly @@ -1176,8 +1176,7 @@ end % level2dict /.default_resource_dir /.resource_dir_name /.fonttempstring /.scannextfontdir % from gs_fonts.ps -] -{systemdict exch .forceundef} forall +] systemdict .undefinternalnames [ /.definedefaultcs @@ -1192,5 +1191,5 @@ end % level2dict /.resourceexec /.undefinedresource /.vmused -] -{level2dict exch .forceundef} forall +] dup level2dict .undefinternalnames +systemdict .undefinternalnames diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_resmp.ps b/Master/tlpkg/tlgs/Resource/Init/gs_resmp.ps index c7122e9a26d..ba17df60a3f 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_resmp.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_resmp.ps @@ -257,7 +257,7 @@ currentpacking //false setpacking } ifelse } ifelse RESMPDEBUG { (resmp FindResource end) = } if - } bind def + } .bind def /ResourceStatus % <Name> ResourceStatus <status> <size> true % <Name> ResourceStatus false @@ -292,7 +292,7 @@ currentpacking //false setpacking } ifelse } ifelse RESMPDEBUG { (resmp ResourceStatus end) = } if - } bind def + } .bind def /ResourceFileName % <Name> <scratch> ResourceFileName <string> { RESMPDEBUG { (resmp ResourceFileName beg ) print 1 index = } if @@ -314,7 +314,7 @@ currentpacking //false setpacking RESMPDEBUG { (resmp ResourceFileName : retrieving ) print dup = } if } ifelse RESMPDEBUG { (resmp ResourceFileName end) = } if - } bind def + } .bind def /ResourceForAll % <template> <proc> <scratch> ResourceForAll - { RESMPDEBUG { (resmp ResourceForAll beg ) print CategoryName =string cvs print ( ) print 2 index = } if @@ -367,7 +367,7 @@ currentpacking //false setpacking % Make the enumerator and apply it : //MakeResourceEnumerator exec exec RESMPDEBUG { (resmp ResourceForAll end)= } if - } bind def + } .bind def /GetCIDSystemInfoFromMap % <Name> GetCIDSystemInfoFromMap <Name> % <Name> GetCIDSystemInfoFromMap <dict> diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_setpd.ps b/Master/tlpkg/tlgs/Resource/Init/gs_setpd.ps index f84a495e37a..0733af0fbb6 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_setpd.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_setpd.ps @@ -497,7 +497,7 @@ SETPDDEBUG { (Result of putting.) = pstack flush } if dup length dict exch { dup type /dicttype eq { .copytree } if 2 index 3 1 roll put } forall -} bind def +} def /currentpagedevice { .currentpagedevice { @@ -674,7 +674,7 @@ SETPDDEBUG { (Result of putting.) = pstack flush } if } ifelse } forall pop -} bind executeonly odef +} .bind executeonly odef currentdict /0Policy undef currentdict /1Policy undef @@ -1003,7 +1003,7 @@ SETPDDEBUG { (Installing.) = pstack flush } if //.postinstall exec } ifelse setglobal % return to original VM allocation mode -} bind executeonly odef +} .bind executeonly odef % We break out the code after calling the Install procedure into a % separate procedure, since it is executed even if Install causes an error. @@ -1030,14 +1030,15 @@ SETPDDEBUG { (Installing.) = pstack flush } if /.trysetparams /.installpagedevice /.postinstall - /.copytree /.defaultdeviceparams /.makecurrentpagedevice /.mergespecial /.requiredattrs + /.applypolicies +% /.copytree % /.uninstallpagedevice % (called from C code) -] -{currentdict exch .forceundef} forall +] dup currentdict .undefinternalnames +systemdict .undefinternalnames end % level2dict .setlanguagelevel diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_ttf.ps b/Master/tlpkg/tlgs/Resource/Init/gs_ttf.ps index e34967dd78d..74043d16b0c 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_ttf.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_ttf.ps @@ -31,9 +31,9 @@ % Augment the FONTPATH machinery so it recognizes TrueType fonts. /.scanfontheaders where { - pop /.scanfontheaders [ - .scanfontheaders aload pop (\000\001\000\000*) (true*) (wOFF*) - ] def + /.scanfontheaders [ + /.scanfontheaders .systemvar aload pop (\000\001\000\000*) (true*) (wOFF*) + ] put } if % ---------------- Automatic Type 42 generation ---------------- % @@ -74,7 +74,7 @@ } ifelse } for exch pop -} bind def +} .bind def % Make /MacRomanEncodingForTrueType including additional % characters in Mac OS Roman encoding, which is missing @@ -158,8 +158,8 @@ <80000000> } ifelse def /curxuid { % - curxuid <int> - .getCPSImode - //false .setCPSImode + //.getCPSImode + //false //.setCPSImode 0 xuidstring { exch 8 bitshift exch add } forall % for tbe benefit of pdfwrite/ps2write we want the resulting XUID contents % to fit into a 32 bit value @@ -167,8 +167,8 @@ { 16#ffffffff idiv } if - exch .setCPSImode -} bind def + exch //.setCPSImode +} .bind def /nextxuid { % - nextxuid - 3 -1 0 { xuidstring 1 index 2 copy get dup 255 ne { @@ -180,61 +180,61 @@ % <string> <index> getu16 <integer> /getu16 { 2 copy get 8 bitshift 3 1 roll 1 add get add -} bind def +} .bind def % <string> <index> gets16 <integer> /gets16 { getu16 16#8000 xor 16#8000 sub -} bind def +} .bind def % <string> <index> getu32 <integer> /getu32 { 2 copy getu16 16 bitshift 3 1 roll 2 add getu16 add -} bind def +} .bind def % <string> <index> gets32 <integer> /gets32 { 2 copy gets16 16 bitshift 3 1 roll 2 add getu16 add -} bind def +} .bind def % <string|array> <index> getu16 <integer> /getu16a { 2 getinterval_from_stringarray 0 getu16 -} bind def +} .bind def % <string|array> <index> gets16 <integer> /gets16a { 2 getinterval_from_stringarray 0 gets16 -} bind def +} .bind def % <string|array> <index> getu32a <integer> /getu32a { 4 getinterval_from_stringarray 0 getu32 -} bind def +} .bind def % <string|array> <index> gets32a <integer> /gets32a { 4 getinterval_from_stringarray 0 gets32 -} bind def +} .bind def 16#ffffffff 0 gt { % 64-bit sign extension { /gets32 /gets32a} { mark 1 index load aload pop { 16#80000000 xor 16#80000000 sub } aload pop //.packtomark exec cvx def - } bind forall + } .bind forall } if % <string> <index> <integer> putu16 - /putu16 { 3 copy -8 bitshift put exch 1 add exch 16#ff and put -} bind def +} .bind def % <string> <index> <integer> putu32 - /putu32 { 3 copy -16 bitshift putu16 exch 2 add exch 16#ffff and putu16 -} bind def +} .bind def % <nametable> <nameid> findname <string> true % <nametable> <nameid> findname false @@ -270,7 +270,7 @@ TTFDEBUG { dup { ( = ) print 1 index //== exec } { ( not found) = } ifelse } if -} bind def +} .bind def % <namerecord> is2byte <bool> /is2byte { @@ -286,7 +286,7 @@ dup length 1 sub 2 index lt {exch pop dup length 1 sub}{exch} ifelse get exec -} bind def +} .bind def % <string> is2byte2 <bool> /is2byte2 { @@ -302,7 +302,7 @@ } for exch pop } ifelse -} bind def +} .bind def % <string2> string2to1 <string> /string2to1 { @@ -310,7 +310,7 @@ 0 1 3 index length 1 sub { 3 index 1 index 2 mul 1 add get put dup } for pop exch pop -} bind def +} .bind def % Each procedure in this dictionary is called as follows: % <encodingtable> proc <glyph dictionary> @@ -320,7 +320,7 @@ mark 0 3 -1 roll { 1 index 1 add } forall pop .dicttomark - } bind + } .bind 2 { % Apple 16bit CJK (ShiftJIS etc) % /sHK_sz subHeaderKey_size % 1 * uint16 @@ -398,7 +398,7 @@ } for pop cmapf2_glyph_array - } bind + } .bind 4 { % Microsoft/Adobe segmented mapping. /etab exch def /nseg2 etab 6 getu16a def @@ -418,7 +418,6 @@ } bind def /glyphs 0 dict def - /numcodes 0 def /code 0 def % neg2 is number of segments x 2. A format 4 cmap, with usable % mappings cannot (according to the spec) have only 1 segment, % since format 4 requires a closing segment with start and end @@ -429,6 +428,16 @@ % segments - this works as we don't rely on the terminating segment % but use the loop counter to spot completion - effrectively, we % ignore the closing segment when it's present, anyway. + % + % This loop and/or putglyph do not account for out of spec fonts + % that have repeated or overlapping ranges in the segments. As we + % write the code/gid to a PS dictionary, later encounters with a + % given code will overwrite the earlier one(s). As this is outside + % of the spec, it's not clear how other consumers handle this + % condition, so we'll await a suitable example before making changes. + % Two choices are: drop later repeated/overlapping segments entirely, + % or only use codes from later, overlapping segments not already set + % by the earlier segment. (Inspired by Bug 700968). 0 2 nseg2 dup 4 lt {pop 4}if 3 sub { /i2 exch def /scode startc i2 getu16a def @@ -436,13 +445,7 @@ % Bug 693538: see above scode 0 eq ecode 0 eq and not { scode ecode 1 add gt { /ecode scode 1 add def } if % Bug 691326. See above. - - numcodes scode firstcode sub - % Hack for fonts that have only 0x0000 and 0xf000 ranges - %dup 16#e000 ge { 255 and } if - % the previous line is obstructive to CJK fonts, so it was removed - exch sub 0 .max dup /code exch code exch add def - ecode scode sub 1 add add numcodes add /numcodes exch def + /code scode def /delta iddelta i2 gets16a def TTFDEBUG { (scode=) print scode =only @@ -462,7 +465,7 @@ } ifelse } if } for glyphs /glyphs //null def % for GC - } bind + } .bind 6 { % Single interval lookup. dup 6 getu16a /firstcode exch def dup 8 getu16a /ng exch def @@ -474,7 +477,7 @@ dup firstcode add exch 2 mul 10 add 4 index exch getu16a 3 copy put pop pop } for pop exch pop - } bind + } .bind 12 { % Microsoft/Adobe segmented mapping. /etab exch def /glyphs 0 dict def @@ -493,7 +496,7 @@ } for } for glyphs /glyphs //null def % for GC - } bind + } .bind .dicttomark readonly def % cmapformats % <cmaptab> cmapdict <glyph dictionary> @@ -509,7 +512,7 @@ TTFDEBUG { (cmap: length=) print dup length = dup === } if -} bind def +} .bind def /get_from_stringarray % <array|string> <offset> get_from_stringarray <int> { 1 index type /stringtype eq { @@ -523,7 +526,7 @@ } ifelse } forall } ifelse -} bind def +} .bind def /getinterval_from_stringarray % <array|string> <offset> <length> getinterval_from_stringarray <string> { % May allocate a string in VM. @@ -571,7 +574,7 @@ ] } ifelse } ifelse -} bind def +} .bind def /string_array_size % <array|string> string_array_size <int> { dup type /stringtype eq { @@ -579,7 +582,7 @@ } { 0 exch { length add } forall } ifelse -} bind def +} .bind def % Each procedure in this dictionary is called as follows: % posttable <<proc>> glyphencoding @@ -692,18 +695,18 @@ } if } ifelse - } bind + } .bind 16#00030000 { % No map. pop [ ] - } bind + } .bind .dicttomark readonly def % postformats /call.readtable { .readtable -} bind def +} .bind def /call.readbigtable { .readbigtable -} bind def +} .bind def % Each procedure in this dictionary is called as follows: % <file> <length> -proc- <string|array_of_strings> @@ -743,7 +746,7 @@ def % <file> <length> .skiptable <string> /.skiptable { pop pop () -} bind def +} .bind def % Read a table as a single string. % <file> <length> .readtable <string> @@ -757,7 +760,7 @@ def % this explicitly here. 3 -1 roll exch dup () ne { readstring } if pop pop -} bind def +} .bind def % Read a big table (one that may exceed 64K). % <file> <length> .readbigtable <string[s]> @@ -773,7 +776,7 @@ def } loop .readtable ] exch vmreclaim } ifelse -} bind def +} .bind def end readonly def % .loadttfontdict @@ -856,7 +859,7 @@ end readonly def % .loadttfontdict 2 index 12 3 -1 roll putu32 } if pop pop } for -} bind executeonly def +} .bind executeonly def @@ -903,7 +906,7 @@ end readonly def % .loadttfontdict { exch 4 getu32 exch 4 getu32 lt } .sort def } ifelse -} bind def +} .bind def /.file_table_pos_names mark @@ -970,7 +973,7 @@ mark } ifelse /fpos fpos tclen add def } for -} bind def +} .bind def % Find the string in a list of strings that includes a given index. % <strings> <index> .findseg <string> <index'> @@ -979,7 +982,7 @@ mark dup length 2 index gt { exch exit } if length sub } forall -} bind def +} .bind def % - .makesfnts - % Defines checksum, getloca, head, locatable, numloca, post, sfnts, upem @@ -1052,7 +1055,7 @@ mark } ifelse TTFDEBUG { (post=) print dup //== exec } if def -} bind def +} .bind def % - .ttkeys <key> <value> ... /.ttkeys { @@ -1092,7 +1095,7 @@ mark count ttkeycount sub array astore dup { //== exec } forall aload pop } if /sfnts sfnts -} bind def +} .bind def % ---------------- Standard TrueType font loading ---------------- % @@ -1116,7 +1119,7 @@ mark /cmapsub 2 index def % () [] exch 4 getu32 1 index string_array_size 1 index sub getinterval_from_stringarray /cmaptab exch def -} bind def +} .bind def % - .pickcmap_with_xlatmap - % Defines cmapsub, cmaptab @@ -1180,7 +1183,7 @@ mark QUIET not { (True Type font doesn't contain a charset listed in gs/lib/xlatmap.) = } if /.pickcmap_with_xlatmap cvx /invalidfont signalerror } if % -} bind def +} .bind def % - .pickcmap - % Defines cmapsub, cmaptab @@ -1384,7 +1387,7 @@ currentdict /.pickcmap_with_no_xlatmap .undef pop 1 add % () v+1 } for pop -} bind def +} .bind def % <CIDSystemInfo dict> <dict> .definettcidfont <font> /.definettcidfont { @@ -1413,7 +1416,7 @@ currentdict /.pickcmap_with_no_xlatmap .undef end end end dup /CIDFontName get exch /CIDFont defineresource -} bind def +} .bind def % <CIDSystemInfo dict> <file> <Substite name> .loadttcidfont <cidtype2font> /.loadttcidfont { @@ -1490,7 +1493,7 @@ currentdict /.pickcmap_with_no_xlatmap .undef } for % Stack: false plat+enc cmap || subtable true plat+enc cmap pop pop -} bind def +} .bind def % Build .symbol_list for .pdfcharkeys . % It is a dictionary containing all SymbolEncoding glyph names @@ -1509,7 +1512,7 @@ currentdict /.pickcmap_with_no_xlatmap .undef exch //.symbol_list 3 1 roll put } for pop -} bind exec +} .bind exec % Create .GS_extended_SymbolEncoding as inverse of .symbol_list . { @@ -1518,7 +1521,7 @@ currentdict /.pickcmap_with_no_xlatmap .undef exch 2 index 3 1 roll put } forall .defineencoding -} bind exec +} .bind exec /.hexdigits (0123456789ABCDEF) def @@ -1529,7 +1532,7 @@ currentdict /.pickcmap_with_no_xlatmap .undef 70 le and 3 1 roll and or -} bind def +} .bind def /.popfex { pop //false exit } bind def /.pop3ex { pop pop pop exit } bind def @@ -1579,7 +1582,7 @@ currentdict /.pickcmap_with_no_xlatmap .undef put exit } loop } if -} bind def +} .bind def % <chartoglyphmap> <subcmap> <AGL> .pdfmapchars /CharStrings <charstrings> /.pdfmapchars { @@ -1621,7 +1624,7 @@ currentdict /.pickcmap_with_no_xlatmap .undef } forall dup /.notdef 0 put -} bind def +} .bind def % <subtable> .pdfmapsymbolic /Encoding [] /CharStrings <<>> /.pdfmapsymbolic { @@ -1652,7 +1655,7 @@ currentdict /.pickcmap_with_no_xlatmap .undef /.notdef 0 def /Encoding exch /CharStrings currentdict end -} bind def +} .bind def % - .pdfcharkeys /CharStrings <charstrings> /Encoding <encoding> /.pdfcharkeys { @@ -1753,7 +1756,7 @@ currentdict /.pickcmap_with_no_xlatmap .undef } ifelse } if TTFDEBUG { (.pdfcharkeys end) = } if -} bind executeonly def +} .bind executeonly def % <file> <is_symbolic> <Encoding|null> <FontName> .loadpdfttfont <type42font> /.loadpdfttfont { @@ -1891,7 +1894,7 @@ currentdict /.pickcmap_with_no_xlatmap .undef //false } ifelse f closefile end end -} bind def +} .bind def /.findwoffname { //true 0 //.loadwofftables exec @@ -1918,7 +1921,7 @@ currentdict /.pickcmap_with_no_xlatmap .undef //false } ifelse f closefile end end -} bind def +} .bind def /tt_tag_dict << <00010000> 0 (true) 0 (typ1) 0 (ttcf) 0 >> readonly def /ttf_otf_tag_dict << <00010000> 0 (true) 0 (typ1) 0 (ttcf) 0 (OTTO) 0>> readonly def @@ -1934,11 +1937,11 @@ currentdict /.pickcmap_with_no_xlatmap .undef % <file> .is_ttf_or_otf <bool> /.is_ttf_or_otf { dup 0 setfileposition (1234) .peekstring { //ttf_otf_tag_dict exch known } { //false } ifelse -} bind def +} .bind def /.is_woff { dup 0 setfileposition (1234) .peekstring { //woff_tag_dict exch known } { //false } ifelse -} bind def +} .bind def % <file> <key> .findfontvalue <value> true % <file> <key> .findfontvalue false @@ -1965,7 +1968,7 @@ currentdict /.pickcmap_with_no_xlatmap .undef .findnonttfontvalue } ifelse } ifelse -} bind executeonly def +} .bind executeonly def % Load a font file that might be a TrueType font. % <file> .loadfontfile - @@ -1984,7 +1987,7 @@ currentdict /.pickcmap_with_no_xlatmap .undef .loadnonttfontfile } ifelse } ifelse -} bind def +} .bind def % Undef the local utility funcs [ @@ -1995,8 +1998,7 @@ currentdict /.pickcmap_with_no_xlatmap .undef /woff_tag_dict /.is_ttf_or_otf /.is_woff -] -{currentdict exch .undef} forall +] currentdict .undefinternalnames % ----- END .loadfontfile that supports possible TrueType font ------ % Undef these, not needed outside this file @@ -2020,4 +2022,4 @@ currentdict /.pickcmap_with_no_xlatmap .undef /.pdfmapsymbolic /.pdfcharkeys /.pdfmapchars -] {systemdict exch .forceundef} forall +] systemdict .undefinternalnames diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_type1.ps b/Master/tlpkg/tlgs/Resource/Init/gs_type1.ps index 6c7735bc0cc..a039ccee359 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_type1.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_type1.ps @@ -118,25 +118,25 @@ ( to be the same as glyph: ) print 1 index //== exec } if 3 index exch 3 index .forceput % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname - } + }executeonly {pop} ifelse - } forall + } executeonly forall pop pop - } + } executeonly { pop pop pop } ifelse - } + } executeonly { % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname pop pop } ifelse - } forall + } executeonly forall 3 1 roll pop pop - } if + } executeonly if pop dup /.AGLprocessed~GS //true .forceput - } if + } executeonly if %% We need to excute the C .buildfont1 in a stopped context so that, if there %% are errors we can put the stack back sanely and exit. Otherwise callers won't diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_base.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_base.ps index 1a218f42fbf..02503eef8bc 100644 --- a/Master/tlpkg/tlgs/Resource/Init/pdf_base.ps +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_base.ps @@ -157,7 +157,7 @@ currentdict /num-chars-dict .undef { dup ==only () = flush } ifelse % PDFSTEP - } if % PDFDEBUG + } executeonly if % PDFDEBUG 2 copy .knownget { exch pop exch pop exch pop exec } { @@ -223,7 +223,7 @@ currentdict /num-chars-dict .undef } ifelse } ifelse } ifelse -} bind executeonly odef +} bind executeonly def /PDFScanRules_true << /PDFScanRules //true >> def /PDFScanRules_null << /PDFScanRules //null >> def /.pdfrun { % <file> <opdict> .pdfrun - diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps index e18a7c27f31..a359a9c11c3 100644 --- a/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps @@ -501,8 +501,8 @@ end ( Output may be incorrect.\n) pdfformaterror //pdfdict /.gs_warning_issued //true .forceput PDFSTOPONERROR { /gs /undefined signalerror } if - } if - } + } executeonly if + } executeonly ifelse } bind executeonly def @@ -911,6 +911,16 @@ currentdict /csncompdict undef << exch { oforce resolvecolorspace } forall >> /Colorants exch >> % Finish new attributes dict } if + % devn_array devn_array <<..attributes..>> + 1 index 4 oget /Process knownoget { + dup /ColorSpace knownoget { + 1 index exch resolvecolorspace /ColorSpace exch put + } if + % devn_array devn_array <<..attributes..>> <<..Process..>> + 1 index + /Process 3 -1 roll + put + } if 4 exch put % Put resolved or new attributes dict } if } bind executeonly def @@ -1142,7 +1152,7 @@ currentdict end readonly def .setglobal pdfformaterror } executeonly ifelse - } + } executeonly { currentglobal //pdfdict gcheck .setglobal //pdfdict /.Qqwarning_issued //true .forceput @@ -1150,8 +1160,8 @@ currentdict end readonly def pdfformaterror } executeonly ifelse end - } ifelse - } loop + } 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 @@ -1165,14 +1175,14 @@ currentdict end readonly def .setglobal pdfformaterror } executeonly ifelse - } + } executeonly { currentglobal //pdfdict gcheck .setglobal //pdfdict /.Qqwarning_issued //true .forceput .setglobal pdfformaterror } executeonly ifelse - } if + } executeonly if pop % restore pdfemptycount @@ -1386,7 +1396,6 @@ drawopdict begin /W* { W* } executeonly def /sh_save 1 array def - /sh_group << /Subtype /Group /Isolated //true >> readonly def /do_shade { 0 .setoverprintmode @@ -1407,38 +1416,19 @@ drawopdict begin setfillstate resolvesh //sh_save 0 save put PDFusingtransparency { - .currentSMask //null ne { - //sh_group - 1 index /BBox knownoget { - { oforce } forall - } { - gsave clippath pathbbox grestore - } ifelse - .begintransparencygroup - } if - dup checkOPtrans exch 1 index { - % We need to push a non-isolated, non-knockout transparency group and - % perform the operation in CompatibleOverprint mode, then end the - % transparency group. Do the begintransparencygroup step here. - mark /Subtype /Group /Isolated //false .dicttomark - 1 index /BBox knownoget { - { oforce } forall - } { - gsave clippath pathbbox grestore - } ifelse - .begintransparencygroup - exch .currentblendmode exch .currentopacityalpha exch 4 -1 roll % save current values - /CompatibleOverprint .setblendmode 1 .setopacityalpha - } if - //do_shade exec - { - .endtransparencygroup .setopacityalpha .setblendmode % end the CompatibleOverprint group - } if - .currentSMask //null ne { - .endtransparencygroup - } if + gsave + dup /BBox knownoget { + { oforce } forall + 4 2 roll moveto exch 0 lineto 0 exch lineto closepath + } { + clippath + } ifelse + //null setup_trans + grestore + //do_shade exec + teardown_trans } { - //do_shade exec + //do_shade exec } ifelse //sh_save 0 get restore } { @@ -1706,6 +1696,95 @@ currentdict /jp2_csp_dict .undef /DecodeParms exch put % <resdict> } bind executeonly def +% Add a key-value pair to the all the /DecodeParms +% dictionaries (i.e. handle the array) +% Copy the objects to avoid spoiling shared ones. +% <resdict> <patch dict> -> <resdict> +/add-to-all-params { + 1 index % <resdict> <patch dict> <resdict> + /Filter knownoget + { % <resdict> <patch dict> </name or [array]> + dup type /arraytype eq + { + length % <resdict> <patch dict> <len> + dup 0 gt + { + 2 index /DecodeParms + knownoget + { + oforce_recursive % resolve indirect references + exch pop % <resdict> <patch dict> [array] + [ + exch + { + dup type /dicttype eq + { + mark exch {} forall .dicttomark + } + { + pop 1 dict + } ifelse + } forall + ] % <resdict> <patch dict> [array] + } + { % <resdict> <patch dict> <len> + % create an array of dictionaries + [ + 0 1 4 -1 roll 1 sub + { pop 1 dict } for + ] + % <resdict> <patch dict> [array] + } ifelse + dup % <resdict> <patch dict> [array] [array] + { % <resdict> <patch dict> [array] [dict] + 2 index % <resdict> <patch dict> [array] [dict] <patch dict> + { % <resdict> <patch dict> [array] [dict] </key> <value> + 2 index % <resdict> <patch dict> [array] [dict] </key> <value> [dict] + 3 1 roll + put + } forall + pop + } forall + % <resdict> <patch dict> [array] + exch pop + % <resdict> [dict/array] + 1 index exch /DecodeParms exch put + } + { + pop pop + } ifelse + } + { % <resdict> <patch dict> </name> + pop + 1 index + /DecodeParms knownoget + { + oforce_recursive + dup type /dicttype eq + { + mark exch {} forall .dicttomark + } + { + pop 1 dict + } ifelse + } + { + 1 dict + } ifelse % <resdict> <patch dict> [dict] + + 1 index % <resdict> <patch dict> [dict] <patch dict> + { % <resdict> <patch dict> [dict] </key> <value> + 2 index + 3 1 roll put + } forall + exch pop + % <resdict> [dict/array] + 1 index exch /DecodeParms exch put + } ifelse + } + {pop} ifelse +} bind def + /last-ditch-bpc-csp { currentdict /BitsPerComponent oknown not { ( **** Error: image has no /BitsPerComponent key; assuming 8 bit.\n) @@ -1825,6 +1904,9 @@ currentdict /jp2_csp_dict .undef % Even though we're going to read data, % pass false to resolvestream so that % it doesn't try to use Length (which may not be present). + + % Bug 701083: We add a /ErrsAsEOD key to the DecodeParms here too. + <</ErrsAsEOD //true>> //add-to-all-params exec //false resolvestream /DataSource exch def //true } { @@ -1971,89 +2053,10 @@ currentdict /jp2_csp_dict .undef % filter, create one and add a /Height key. This is to solve the problem % in Bug #695116 where a JPEG image has a bad height, which is later % fixed up using a DNL marker. By placing the image height from the - % PDF in the DeoceParms we cna use it in the DCTDecode filter to + % PDF in the DecodeParms we can use it in the DCTDecode filter to % work around this. - dup /Filter knownoget { % <<stream dict>> /name or [array] - dup type /arraytype eq { - % <<stream dict>> [array of names] - length % <<stream dict>> number of filters - 1 index /DecodeParms knownoget { - exch pop % drop length of Filter array, the DecodeParams has 1 entry per filter - % <<stream dict>> [array of decodeparams] - } { - % No deocde params, we must make an array of them - % <<stream dict>> number of filters - array % <<stream dict>> [] - dup % <<stream dict>> [] [] - 2 index /DecodeParms exch % <<stream dict>> [] [] /DecodeParms <<stream dict>> - 3 1 roll % <<stream dict>> <<stream dict>> [] /DecodeParms - exch put % <<stream dict>> [] - } ifelse - dup length 1 sub % <<stream dict>> [] arraylength-1 - 0 1 3 -1 roll % <<stream dict>> [] 0 1 arraylength-1 - { % <<stream dict>> [] loopcount - 1 index % <<stream dict>> [] loopcount [] - 2 copy % <<stream dict>> [] loopcount [] loopcount [] - exch - get % <<stream dict>> [] loopcount [] <<>> or -null- - dup //null eq { - pop exch % <<stream dict>> [] [] loopcount - <</Height - 5 index /Height oget % <<stream dict>> [] [] loopcount << /Height Height - round cvi - >> - put % <<stream dict>> [] - }{ % - oforce_recursive % resolve any indirect references - dup type /dicttype eq { - % <<stream dict>> [] loopcount [] <<>> - /Height % <<stream dict>> [] loopcount [] <<>> /Height - 5 index /Height oget % <<stream dict>> [] loopcount [] <<>> /Height Height - round - cvi - put pop pop % <<stream dict>> [] - }{ - %% bogus entry, throw it away and create a new one - pop exch % <<stream dict>> [] loopcount [] - <</Height - 5 index /Height oget % <<stream dict>> [] [] loopcount << /Height Height - round cvi - >> - put % <<stream dict>> [] - } ifelse - }ifelse - } for - pop % <<stream dict>> - }{ - pop % <<stream dict>> - dup /DecodeParms knownoget { - oforce_recursive % resolve any indirect references - dup type /dicttype eq { - % <<stream dict>> <<decode parms dict>> - /Height 2 index % <<stream dict>> <<decode parms dict>> /Height <<stream dict>> - /Height oget % <<stream dict>> <<decode parms dict>> /Height ImageHeight - round cvi - put % <<stream dict>> - }{ - %% bogus entry, throw it away and create a new one - pop % <<image dict>> <<stream dict>> [] - <</Height % <<stream dict>> <<image dict>> << /Height - 2 index /Height oget % <<stream dict>> <<image dict>> << /Height Height - round cvi - >> - 1 index exch /DecodeParms exch put % <<stream dict> <<image dict>> - } ifelse - }{ - dup % <<stream dict>> <<stream dict>> - /DecodeParms <</Height % <<stream dict>> <<stream dict>> /DecodeParms << /Height - 3 index % <<stream dict>> <<stream dict>> /DecodeParms << /Height <<stream dict>> - /Height oget - round cvi - >> % <<stream dict>> <<stream dict>> /DecodeParms << /Height ImageHeight>> - put % <<stream dict>> - }ifelse - }ifelse - } if + % Bug 701083: We add a /ErrsAsEOD key to the DecodeParms here too. + << /Height 2 index /Height oget round cvi /ErrsAsEOD //true >> //add-to-all-params exec % Even though we're going to read data, % pass false to resolvestream so that @@ -2064,6 +2067,7 @@ currentdict /jp2_csp_dict .undef } bind executeonly def currentdict /add-to-last-param undef +currentdict /add-to-all-params undef currentdict /last-ditch-bpc-csp undef /DoImage { @@ -2124,13 +2128,15 @@ currentdict /last-ditch-bpc-csp undef 1 BitsPerComponent bitshift 1 sub //false 2 index { % stack: max_value result_bool value dup 0 lt exch 3 index gt or or - } forall exch pop { + } forall exch pop + { ( **** Error: Some elements of Mask array are out of range.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror ColorSpace dup type /arraytype eq { 0 oget } if /Indexed eq - BitsPerComponent 1 eq and { + BitsPerComponent 1 eq and + { % AR9 treats Indexed 1 bpc images specially. Bug 692852 see also 697919 and 689717. dup 0 oget dup 0 lt exch 1 BitsPerComponent bitshift ge or { @@ -2140,37 +2146,37 @@ currentdict /last-ditch-bpc-csp undef % Second component is invalid; AR9 replaces it with 1. [ exch 0 oget 1 ] } ifelse - } { - % AR5, AR9 do this for most cases. Bug 690786. - [ exch { 1 BitsPerComponent bitshift 1 sub and } forall ] - } ifelse - } { - ColorSpace dup type /arraytype eq { 0 oget } if /DeviceGray eq - BitsPerComponent 1 eq and { - %% For DeviceGray, try clamping the values to 0 and 1 respectively - dup 0 oget - dup 0 lt exch 1 gt or { - dup 0 oget - dup 0 lt { - pop dup 0 0 put - }{ - dup 0 1 put - } ifelse - } if - dup 1 oget - dup 0 lt exch 1 gt or { - dup 1 oget - dup 0 lt { - pop dup 0 0 put + } + { + BitsPerComponent 1 eq { + dup length 2 gt { + % There are too many Mask entries, discard the Mask array + pop //null }{ - dup 0 1 put + % Bug 701468 and 689717, the latter requires us to set the Mask values + % so that the value is calculated from the BPC, the other requires us + % to ignore the Mask. The only difference between the two files is the + % actual range of the Mask values. This may yet need more work. + % Note! Both files are technically invalid.... + + aload 3 1 roll eq { + % There's only one Mask value, but its illegal, substitute with the + % calculated maximum. + [ exch { 1 BitsPerComponent bitshift 1 sub and } forall ] + } { + % The Mask values are not the same. This is a 2 colour image, if + % we mask off any range then the result will be blank, so ignore the Mask + pop //null + } ifelse } ifelse - } if - }{ - % AR5, AR9 do this for most cases. Bug 690786. - [ exch { 1 BitsPerComponent bitshift 1 sub and } forall ] + } { + % We think AR5, AR9 do this for most other cases. Originally Bug 690786, + % but that is actually handled in the /Indexed case above. + [ exch { 1 BitsPerComponent bitshift 1 sub and } forall ] + } ifelse } ifelse - } ifelse + } if + dup //null ne { /MaskColor exch def } { @@ -2231,7 +2237,7 @@ currentdict /last-ditch-bpc-csp undef PDFfile exch setfileposition 0 .endtransparencymask } ifelse - << /Subtype /Group /Isolated //true + << /Subtype /Group /Isolated //true /.image_with_SMask //true % pdfwrite needs : see gs/src/ztrans.c, gs/src/gdevpdft.c % Code to deal with a Matte in the SMask. We know the image dictionary must have an SMask @@ -2241,7 +2247,7 @@ currentdict /last-ditch-bpc-csp undef % We also need to actually set the current colour space to be the same as the group % code only picks up the current colour space, not the space from the dictionary. currentdict /SMask get /Matte known {/CS currentdict /ColorSpace get dup pdfopdict /cs get exec } if - >> 0 0 1 1 .begintransparencygroup + >> 0 0 1 1 .begintransparencygroup doimage .endtransparencygroup % tell the compositor we're done with the SMask. @@ -2309,15 +2315,6 @@ currentdict /last-ditch-bpc-csp undef /doimage { % <imagemask> doimage - % imagedict is currentdict, gets popped from dstack - //null checkOPtrans { - % We need to push a non-isolated, non-knockout transparency group and - % perform the operation in CompatibleOverprint mode, then end the - % transparency group. Do the begintransparencygroup step here. - mark /Subtype /Group /Isolated //false .dicttomark 0 0 1 1 .begintransparencygroup - OPsavedict dup /saveBM .currentblendmode put /saveOA .currentopacityalpha put % save current values - /CompatibleOverprint .setblendmode 1 .setopacityalpha - } if - %% save the current rendering intent .currentrenderintent exch @@ -2339,6 +2336,7 @@ currentdict /last-ditch-bpc-csp undef makemaskimage } if % Stack: datasource imagemask + gsave 1 1 moveto 0 0 lineto /image setup_trans grestore { currentdict end setfillstate //true ValidateDecode { imagemask } } { ColorSpace setgcolorspace currentdict end setfillblend //false ValidateDecode { image } } ifelse @@ -2363,10 +2361,7 @@ currentdict /last-ditch-bpc-csp undef %% restore the rendering intent .setrenderingintent - .currentblendmode /CompatibleOverprint eq { - .endtransparencygroup - OPsavedict dup /saveOA get .setopacityalpha /saveBM get .setblendmode - } if + teardown_trans } bind executeonly def /.paintform { % <formdict> <resdict> <stream> .paintform - @@ -4348,37 +4343,46 @@ currentdict /set_bc_color undef /k {setcmykcolor} /K {setcmykcolor} >> def + dup /DA knownoget { length string /tempstr exch def dup /DA get tempstr copy pop + + gstate + mark { - %% This is kind of ugly, we use token to process the string - %% and process each token separately. - tempstr - token { - exch /tempstr exch def - %% If the token is a name - %% - dup type /nametype eq { - %% Is it a name we want to take actionon - dup DA_Action_Dict exch known { - DA_Action_Dict exch get exec + { + %% This is kind of ugly, we use token to process the string + %% and process each token separately. + tempstr + token { + exch /tempstr exch def + %% If the token is a name + %% + dup type /nametype eq { + %% Is it a name we want to take actionon + dup DA_Action_Dict exch known { + DA_Action_Dict exch get exec + }{ + %% Its not a name we know, is it executable + dup xcheck {exec} if + } ifelse }{ - %% Its not a name we know, is it executable - dup xcheck {exec} if - } ifelse + %% Not a name, just make it executable and execute it + cvx exec + }ifelse }{ - %% Not a name, just make it executable and execute it - cvx exec + exit }ifelse - }{ - exit - }ifelse - } loop + } loop + } stopped + {cleartomark setgstate} + {cleartomark pop} ifelse } { 0 setgray /Helvetica findfont 12 scalefont setfont }ifelse + %% draw the border, if we don't have a border style dictionary, draw a default one. dup /BS knownoget { pop dup drawborder @@ -4401,58 +4405,69 @@ currentdict /set_bc_color undef %% Get the Contents string, if we don't have one, we're done %% 2 index /Contents knownoget { - PDFusingtransparency { - .begintransparencytextgroup - } if - %% Check for UTF16-BE, we probably don't work properly with this yet. - %% - dup 0 get 254 eq 1 index 1 get 255 eq and - { - /FallBackFont /Identity-UTF16-H [/CIDFallBack] composefont 12 scalefont setfont - dup length 2 div 1 sub 0 1 3 -1 roll { - %% llx urx (string) index - 1 index exch 2 mul 2 getinterval %% llx urx (string) (substring) - dup stringwidth pop currentpoint pop add 3 index gt { - currentpoint exch pop 4 index exch 12 sub moveto - } if - show - } for - pop - } - { - %% Heuristic to determine the height (ascender to descender) of the text - %% for when we move down a line. - gsave - /..TextHeight (Hy) //false charpath pathbbox exch pop exch sub exch pop def - grestore - %% and use it immediatley to start the text one line down - %% - currentpoint ..TextHeight sub moveto - - %% Now we process each character code in the string. If we find - %% a /r/ or /n then we drop a line. If the character would end up - %% outside the Annot Rect, then we drop a line before showing it. - %% - dup length 1 sub 0 1 3 -1 roll { - %% llx urx (string) index - 1 index exch get %% llx urx (string) int - dup 10 eq 1 index 13 eq or { - pop - currentpoint exch pop 3 index exch ..TextHeight sub moveto - } { - 1 string dup 0 4 -1 roll - put dup %% llx urx (string) (int) (int) - stringwidth pop currentpoint pop add 3 index gt { - currentpoint exch pop 4 index exch ..TextHeight sub moveto + dup length 0 gt { + PDFusingtransparency { + .begintransparencytextgroup + } if + %% Check for UTF16-BE, we probably don't work properly with this yet. + %% (If the string is less than 4 bytes its either not UTF16-BE or it is + %% but has no actual content) + dup length 4 ge { + dup 0 get 254 eq 1 index 1 get 255 eq and + }{ + //false + } ifelse + + { + /FallBackFont /Identity-UTF16-H [/CIDFallBack] composefont 12 scalefont setfont + dup length 2 div 1 sub 0 1 3 -1 roll { + %% llx urx (string) index + 1 index exch 2 mul 2 getinterval %% llx urx (string) (substring) + dup stringwidth pop currentpoint pop add 3 index gt { + currentpoint exch pop 4 index exch 12 sub moveto } if show - } ifelse - } for + } for + pop + } + { + %% Heuristic to determine the height (ascender to descender) of the text + %% for when we move down a line. + gsave + /..TextHeight (Hy) //false charpath pathbbox exch pop exch sub exch pop def + grestore + %% and use it immediatley to start the text one line down + %% + currentpoint ..TextHeight sub moveto + + %% Now we process each character code in the string. If we find + %% a /r/ or /n then we drop a line. If the character would end up + %% outside the Annot Rect, then we drop a line before showing it. + %% + dup length 1 sub 0 1 3 -1 roll { + %% llx urx (string) index + 1 index exch get %% llx urx (string) int + dup 10 eq 1 index 13 eq or { + pop + currentpoint exch pop 3 index exch ..TextHeight sub moveto + } { + 1 string dup 0 4 -1 roll + put dup %% llx urx (string) (int) (int) + stringwidth pop currentpoint pop add 3 index gt { + currentpoint exch pop 4 index exch ..TextHeight sub moveto + } if + show + } ifelse + } for + pop + }ifelse + PDFusingtransparency { + .endtransparencytextgroup + } if + } + { pop - }ifelse - PDFusingtransparency { - .endtransparencytextgroup - } if + } ifelse } if pop pop //endannottransparency exec @@ -5029,18 +5044,17 @@ currentdict /drawannottypes undef currentdict end readonly def /preserveannot { % <annot> preserveannot - - dup /.gs.pdfobj# known { dup /.gs.pdfobj# undef } if - dup annotvisible { - gsave - dup dup /Subtype knownoget { - dup //.PDFDrawAnnotType? exec + gsave + dup dup /Subtype knownoget { + dup //.PDFDrawAnnotType? exec + { + //preserveannottypes exch .knownget { exec } { //true } ifelse { - //preserveannottypes exch .knownget { exec } { //true } ifelse - { + dup annotvisible { dup calc_annot_scale 2 copy mul 0 ne { 3 -1 roll drawwidget @@ -5049,18 +5063,20 @@ currentdict end readonly def ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror }ifelse % Draw rejected annots as widgets - } if - } - {pop} ifelse - % type known - } { - pop - ( **** Error: Ignoring /Annot dict without required /Subtype entry.\n) - pdfformaterror - ( Output may be incorrect.\n) pdfformaterror - } ifelse - grestore - } if pop % annotvisible + } { + pop + }ifelse + } if + } + {pop} ifelse + % type known + } { + pop + ( **** Error: Ignoring /Annot dict without required /Subtype entry.\n) + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + } ifelse + grestore } bind executeonly def currentdict /preserveannottypes undef diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps index 9fb85f60b60..81b7af13c7b 100644 --- a/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps @@ -621,89 +621,149 @@ currentdict end readonly def PDFDEBUG { (.processToUnicode beg) = } if - 2 index /ToUnicode knownoget { - dup type /dicttype eq { dup /File known not } { //true } ifelse { - % We undefine wrong /Length and define /File in stream dictionaries. - % Bug687351.pdf defines /ToUnicode /Identity-H, what is incorrect. - ( **** Warning: Ignoring bad ToUnicode CMap.\n) pdfformatwarning - pop - } { - /PDFScanRules .getuserparam dup //null eq { - pop //PDFScanRules_null - } { - 1 dict dup /PDFScanRules 4 -1 roll put - } ifelse - //PDFScanRules_true setuserparams - PDFfile fileposition - 3 -1 roll - count 1 sub - countdictstack - { //false resolvestream - % Following Acrobat we ignore everything outside - % begincodespacerange .. endcmap. - dup 0 (begincodespacerange) /SubFileDecode filter flushfile - /CIDInit /ProcSet findresource begin - //ToUnicodeCMapReader begin - 12 dict begin - /CMapType 2 def - mark exch % emulate 'begincodespacerange' - 0 (endcmap) /SubFileDecode filter cvx /begincmap cvx exch 2 .execn - endcmap - userdict /.lastToUnicode currentdict put - end end end - } - PDFSTOPONERROR { - { exec } 0 get - //false - 5 -2 roll - 5 - } { - { stopped } 0 get - 4 2 roll - 4 - } ifelse - array astore cvx exec + 2 index /ToUnicode knownoget + { + dup type /nametype eq { + % This is contrary to the specification but it seems that Acrobat at least will accept + % a ToUnicode with a value of Identity-H *and* will use that for search, copy/paste. + % We can't pass through a name, so the best we can do is build a GlyphNames2Unicode + % map matching that which would have been generated by a full 16-bit Identity CMap + % + % See bug numbers 701003 and 687351 + % + dup /Identity-H eq 1 index /Identity-V eq or{ + pop + 1 index /FontInfo .knownget not { + currentglobal 2 index dup gcheck setglobal + /FontInfo 5 dict dup 5 1 roll .forceput + setglobal + } executeonly if + dup /GlyphNames2Unicode .knownget not { + //true % No existing G2U, make one + } { + dup wcheck { + //false % Existing, writeable G2U, don't make new one + } { + pop //true % Existing read only G2U, make new one + } ifelse + } ifelse + { + currentglobal exch dup gcheck setglobal + dup /GlyphNames2Unicode 100 dict dup 4 1 roll .forceput + 3 2 roll setglobal + } if % font-res font-dict encoding|null font-info g2u + + 0 1 65535{ + % g2u index + dup dup 256 mod exch 256 idiv % g2u index lo-byte hi-byte + 2 string dup 0 4 -1 roll % g2u index lo-byte () () 0 hi-byte + put % g2u index lo-byte (x) + dup 1 % g2u index lo-byte (x) (x) 1 + 4 -1 roll put % g2u index (x) (x) 1 lo-byte -> dict index (xx) + 2 index % g2u index (xx) dict + 3 1 roll % g2u g2u index (xx) + put % g2u + } for + pop % font-res font-dict encoding|null font-info + pop % font-res font-dict encoding|null + //false % We built a GlyphNames2Unicode table, don't need to process further + } executeonly + { + //true % name is not Identity-V or H, fail by falling through + }ifelse + } executeonly + { + //true + } ifelse % not a name, try as a dictionary (as specified) - countdictstack exch sub 0 .max { end } repeat - count exch sub 2 sub 0 .max { exch pop } repeat - 3 1 roll % Stach the stop flag. - PDFfile exch setfileposition - setuserparams - { - ( **** Warning: Failed to read ToUnicode CMap.\n) pdfformatwarning + % If the ToUnicode isn't a name, or the name isn't Identity-V or -H then follow the specification + % If its not a dictionary type throw an error, otherwise decode it and build a GlyphNames2Unicode + % + { + dup type /dicttype eq { dup /File known not } { //true } ifelse { + % We undefine wrong /Length and define /File in stream dictionaries. + % Bug687351.pdf defines /ToUnicode /Identity-H, what is incorrect. + ( **** Warning: Ignoring bad ToUnicode CMap.\n) pdfformatwarning + pop } { - 1 index /FontInfo .knownget not { - currentglobal 2 index dup gcheck setglobal - /FontInfo 5 dict dup 5 1 roll .forceput - setglobal - } if - dup /GlyphNames2Unicode .knownget not { - //true % No existing G2U, make one + /PDFScanRules .getuserparam dup //null eq { + pop //PDFScanRules_null } { - dup wcheck { - //false % Existing, writeable G2U, don't make new one + 1 dict dup /PDFScanRules 4 -1 roll put + } ifelse + //PDFScanRules_true setuserparams + PDFfile fileposition + 3 -1 roll + count 1 sub + countdictstack + { //false resolvestream + % Following Acrobat we ignore everything outside + % begincodespacerange .. endcmap. + dup 0 (begincodespacerange) /SubFileDecode filter flushfile + /CIDInit /ProcSet findresource begin + //ToUnicodeCMapReader begin + 12 dict begin + /CMapType 2 def + mark exch % emulate 'begincodespacerange' + 0 (endcmap) /SubFileDecode filter cvx /begincmap cvx exch 2 .execn + endcmap + userdict /.lastToUnicode currentdict put + end end end + } + + PDFSTOPONERROR { + { exec } 0 get + //false + 5 -2 roll + 5 + } { + { stopped } 0 get + 4 2 roll + 4 + } ifelse + array astore cvx exec + + countdictstack exch sub 0 .max { end } repeat + count exch sub 2 sub 0 .max { exch pop } repeat + 3 1 roll % Stach the stop flag. + PDFfile exch setfileposition + setuserparams + { + ( **** Warning: Failed to read ToUnicode CMap.\n) pdfformatwarning + } { + 1 index /FontInfo .knownget not { + currentglobal 2 index dup gcheck setglobal + /FontInfo 5 dict dup 5 1 roll .forceput + setglobal + } if + dup /GlyphNames2Unicode .knownget not { + //true % No existing G2U, make one } { - pop //true % Existing read only G2U, make new one + dup wcheck { + //false % Existing, writeable G2U, don't make new one + } { + pop //true % Existing read only G2U, make new one + } ifelse } ifelse + { + currentglobal exch dup gcheck setglobal + dup /GlyphNames2Unicode 100 dict dup 4 1 roll .forceput + 3 2 roll setglobal + } if % font-res font-dict encoding|null font-info g2u + exch pop exch % font-res font-dict g2u encoding|null + userdict /.lastToUnicode get % font-res font-dict g2u Encoding|null CMap + .convert_ToUnicode-into-g2u % font-res font-dict + //null % font-res font-dict //null } ifelse - { - currentglobal exch dup gcheck setglobal - dup /GlyphNames2Unicode 100 dict dup 4 1 roll .forceput - 3 2 roll setglobal - } if % font-res font-dict encoding|null font-info g2u - exch pop exch % font-res font-dict g2u encoding|null - userdict /.lastToUnicode get % font-res font-dict g2u Encoding|null CMap - .convert_ToUnicode-into-g2u % font-res font-dict - //null % font-res font-dict //null } ifelse - } ifelse - } if - PDFDEBUG { - (.processToUnicode end) = - } if - } if - } stopped + } if + PDFDEBUG { + (.processToUnicode end) = + } if + } executeonly if + } executeonly if + } executeonly stopped { .dstackdepth 1 countdictstack 1 sub {pop end} for @@ -850,9 +910,16 @@ setglobal % No available good substitution, use the standard one. pop 1 index .substitutefont } if - dup 3 index ne QUIET not and { + dup 3 index ne { + QUIET not { (Substituting font ) print dup =only ( for ) print 2 index =only (.) = flush + } if + % Send a warning to the device, in case its pdfwrite and we are in PDF/A mode + % In that case the substituted font may not (probably doesn't) have glyphs which + % match the /Widths of the original font, and that will cause a fault with PDF/A + % so we need to let the device know. + /SubstitutedFont /EventInfo .special_op } if pdffindcachedfont % Stack: font-res fontname fontdesc font @@ -1233,19 +1300,20 @@ currentdict /eexec_pdf_param_dict .undef //pdfdict /.Qqwarning_issued //true .forceput } executeonly if Q - } repeat + } executeonly repeat Q - } PDFfile fileposition 2 .execn % Keep pdfcount valid. + } executeonly PDFfile fileposition 2 .execn % Keep pdfcount valid. PDFfile exch setfileposition - } ifelse - } { + } executeonly ifelse + } executeonly + { % PDF Type 3 fonts don't use .notdef % d1 implementation adjusts the width as needed 0 0 0 0 0 0 pdfopdict /d1 get exec } ifelse end end - } bdef + } executeonly bdef dup currentdict Encoding .processToUnicode currentdict end .completefont exch pop } bind executeonly odef @@ -1616,7 +1684,6 @@ currentdict /CMap_read_dict undef dup 2 index /W2 3 -1 roll put .pdfMakeInternalW2 1 index /.internalW2 3 -1 roll put } if - dup /CDevProc 1 index /CIDWProc load /exec load 3 packedarray cvx put exch pop } bind executeonly def @@ -1864,6 +1931,12 @@ currentdict /CMap_read_dict undef % <CIDFont-resource> <CIDFontName> findCIDFont <CIDFont-resource> <font> % CIDFont-resource is not modified. +% In various places we do: +% "findCIDFont dup /OrigFont .knownget {exch pop} if" +% because the CIDFont we find may have been "patched" to apply metrics from +% the PDF file (W, W2, etc). We want to avoid applying those metrics more +% than once, hence retrieving the original, unpatched CIDFont dictionary, +% if it exists. /findCIDFont { { dup /CIDFont resourcestatus { @@ -1883,7 +1956,9 @@ currentdict /CMap_read_dict undef % "Light,Bold" font, don't artificially bolden further dup (Light) tailmatch { - pop cvn findCIDFont dup /FontName .knownget + pop cvn findCIDFont + dup /OrigFont .knownget {exch pop} if + dup /FontName .knownget { (Light) tailmatch exch pop } @@ -1897,13 +1972,16 @@ currentdict /CMap_read_dict undef } { pop - cvn findCIDFont 0.03 makeboldfont + cvn findCIDFont + dup /OrigFont .knownget {exch pop} if + 0.03 makeboldfont } ifelse exit } if (,Italic) tailmatch { exch pop cvn findCIDFont + dup /OrigFont .knownget {exch pop} if [ 1 0 0.3 1 0 0 ] makefont exit } if @@ -1912,7 +1990,9 @@ currentdict /CMap_read_dict undef % see above dup (Light) tailmatch { - pop cvn findCIDFont dup /FontName .knownget + pop cvn findCIDFont + dup /OrigFont .knownget {exch pop} if + dup /FontName .knownget { (Light) tailmatch exch pop } @@ -1926,7 +2006,9 @@ currentdict /CMap_read_dict undef } { pop - cvn findCIDFont 0.03 makeboldfont + cvn findCIDFont + dup /OrigFont .knownget {exch pop} if + 0.03 makeboldfont } ifelse [ 1 0 0.3 1 0 0 ] makefont exit @@ -2045,9 +2127,9 @@ currentdict /CMap_read_dict undef (Will continue, but content may be missing.) = flush } ifelse } if - } if + } executeonly if /findresource cvx /undefined signalerror - } loop + } executeonly loop } bind executeonly odef /buildCIDType0 { % <CIDFontType0-font-resource> buildCIDType0 <font> @@ -2293,15 +2375,14 @@ currentdict /CMap_read_dict undef { exch pop readtype1 } 2 bndef - <01000401> <01000402> <01000403> <01000404> % Type 1C - <01000C02> <01000C03> + <01000401> % Type 1C { exch pop 1 index /Subtype knownoget dup { pop /CIDFontType0 eq } if { readCIDFontType0C } { readType1C } ifelse - } 6 bndef + } bind executeonly def <00010000> (true) (typ1) (ttcf) % TrueType OpenType { exch pop readtruetype @@ -2466,14 +2547,37 @@ currentdict /bndef undef % /key res res desc stream tag //font_tag_dict 1 index known not { + % + % The tag is the first 4 (?) bytes frm the font stream, if we get here then + % it didn't match any of the keys in the dictionary. There seems to be + % a possibility that a PFB font could be undetected (because its only 2 bytes?) + % but the main problem is CFF fonts. These lack a magic number, and the header + % can vary in the last 3 of the 4 bytes. We've now found 7 different possible + % values for these bytes, adding more seems pointless and isn't future proof. + % Instead check the dictionary for its Subtype. + % dup 0 2 getinterval <8001> eq { 0 2 getinterval % /key res res desc stream pfb_tag } { - (12345678>\n) dup /ASCIIHexEncode filter dup 4 -1 roll writestring closefile - ( **** Error: unrecognized font file starts with <) exch concatstrings - pdfformaterror - ( Output may be incorrect.\n) pdfformaterror - /no_stream % /key res res desc stream unknown_tag + 1 index /Subtype known { + 1 index /Subtype get + dup /Type1C eq 1 index /CIDFontType0C eq or exch /CIDFontType1C eq or { + pop <01000401> % discard the data we read and pretend we read the original Type1C tag + //false + }{ + //true + }ifelse + } { + //true % no /Subtype, give up. + }ifelse + + { + (12345678>\n) dup /ASCIIHexEncode filter dup 4 -1 roll writestring closefile + ( **** Error: unrecognized font file starts with <) exch concatstrings + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + /no_stream % /key res res desc stream unknown_tag + }if } ifelse } if //font_tag_dict exch get % /key res res desc stream {proc} diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps index 5305ea6132a..7690bae0f92 100644 --- a/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps @@ -1560,7 +1560,11 @@ currentdict /xref-char-dict undef { stop } if % Check for recursion in the page tree. Bug 689954, MOAB-06-01-2007 + % Make sure that the operand stack is cleaned up in case there's + % an error and we ignore it (bug #700953) + mark verify_page_tree + cleartomark currentdict end } bind executeonly def @@ -1996,6 +2000,11 @@ currentdict /xref-char-dict undef % Check for loops in the 'page tree' but accept an acyclic graph. % - verify_page_tree - /verify_page_tree { + % Run the verification inside a 'stopped' context. Bug #700953 + % has a peculiarly constructed page tree, and a huge number of + % pages, which recurses to a depth beyond the level we can cope + % with on the exec stack. If we ignore that error then we can + { Trailer /Root knownoget { /Pages knownoget { 10 dict begin @@ -2028,6 +2037,16 @@ currentdict /xref-char-dict undef end } if } if + } stopped + { + %% Specific check for syntax error, in this case assume we found a loop in the Pages tree. + %% (see above). Otherwise, just try to process the file anyway. + $error /errorname get /syntaxerror eq { + /verify_page_tree cvx /syntaxerror signalerror + } { + ( **** Error: Something went wrong while checking for recursion in the Page tree. Giving up checking.\n This PDF file may not terminate, if there is a loop in the Pages tree.\n) pdfformaterror + } ifelse + } if } bind executeonly def /pdffindpage? { % <int> pdffindpage? 1 null (page not found) @@ -2686,11 +2705,14 @@ currentdict /PDF2PS_matrix_key undef % (eg GSView 5) then it will not be present, so we must rescan. currentpagedevice /PageUsesTransparency .knownget not {dup pageusestransparency} if dup /PDFusingtransparency exch def { - % If the current device isn't CMYK, or if it is a HighLevelDevice (pdfwrite) we - % don't need the special handling of Overprint transparency, so disable the checking. - currentpagedevice dup /Colors get 4 lt exch /HighLevelDevice known or { - /checkOPtrans { pop //false } def % NB: original will be restored from PDFsave - } if + % If the current device isn't CMYK, or if it is a device that (currently) supports transparency + % we don't need the special handling of Overprint transparency, so disable the checking. + currentpagedevice dup /Colors get 4 lt + exch /HaveTransparency .knownget not { //false } if or + % device needs special Oveprint handling + /setup_trans exch + { /setupSMtrans } { /setupOPtrans } ifelse + load def % Show the page within a PDF 1.4 device filter. 0 .pushpdf14devicefilter { /DefaultQstate qstate store % device has changed -- reset DefaultQstate @@ -2718,7 +2740,7 @@ currentdict /PDF2PS_matrix_key undef .poppdf14devicefilter % NB: reset to DefaultQstate will also restore transfer function /DefaultQstate qstate store % device has changed -- reset DefaultQstate } { - /checkOPtrans { pop //false } def % no-op the check if the page doesn't use transparency + /setup_trans { pop } def % no-op this if the page doesn't use transparency % NB: original will be restored from PDFsave showpagecontents } ifelse @@ -2749,15 +2771,15 @@ currentdict /PDF2PS_matrix_key undef .setglobal pdfformaterror } executeonly ifelse - } + } executeonly { currentglobal //pdfdict gcheck .setglobal //pdfdict /.Qqwarning_issued //true .forceput .setglobal pdfformaterror } executeonly ifelse - } if - } if + } executeonly if + } executeonly if pop count PDFexecstackcount sub { pop } repeat (after exec) VMDEBUG @@ -3518,7 +3540,6 @@ end % pdfdict %% Since each operator is a potential security vulnerability, and any operator listed here %% is not required once the initislisation is complete and functions are bound, we undefine %% the ones that aren't needed at runtime. -/.PDF_UNDEF_OPLIST [ /.pdfawidthshow /.pdfwidthshow /.currentblackptcomp /.setblackptcomp /.setfillcolor /.setfillcolorspace /.setstrokecolor /.setstrokecolorspace /.currentrenderingintent /.setrenderingintent @@ -3544,10 +3565,4 @@ end % pdfdict % undefining these causes errors/incorrect output %/.settextrenderingmode /.setblendmode /.begintransparencygroup /.settextknockout /.setstrokeoverprint /.setfilloverprint %/.currentstrokeoverprint /.currentfilloverprint /.currentfillconstantalpha /.currentstrokeconstantalpha -] def - -DELAYBIND not { -.PDF_UNDEF_OPLIST -{systemdict exch .undef} forall -systemdict /.PDF_UNDEF_OPLIST .undef -} if +] systemdict .undefinternalnames diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps index 285e582eff2..d594035c066 100644 --- a/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps @@ -81,7 +81,13 @@ nodict readonly pop initgraphics //true .setaccuratecurves currentdict /ClipRect knownoget { aload pop rectclip } if - 0 g 0 G //false op //false OP 0 OPM + % inigraphics sets the gstate colorspace and color correctly + % *but* pdfwrite's transparency handling can get upset if we + % don't explicitly set color and space here. + currentcolor currentcolor currentcolorspace dup + .setfillcolorspace .setstrokecolorspace + .setfillcolor .setstrokecolor + //false op //false OP 0 OPM 1 ca 1 CA //null SMask //false AIS /Compatible BM //true TK } bind executeonly def @@ -186,14 +192,14 @@ currentdict /gput_always_allow .undef .setglobal pdfformaterror } executeonly ifelse - } + } executeonly { currentglobal //pdfdict gcheck .setglobal //pdfdict /.Qqwarning_issued //true .forceput .setglobal pdfformaterror } executeonly ifelse - } if + } executeonly if } bind executeonly odef % Save PDF gstate @@ -440,11 +446,12 @@ currentdict /gput_always_allow .undef dup type /booleantype eq { .currentSMask type /dicttype eq { .currentSMask /Processed 2 index .forceput + } executeonly + { + .setSMask + }ifelse } executeonly { - .setSMask - }ifelse - }{ .setSMask }ifelse @@ -666,59 +673,127 @@ end def } ifelse } bind executeonly def -/OPsavedict 2 dict def % for saveOP, saveBM +/OPsaveDstack 6 dict def % for GroupPushed, saveOP, saveSA, saveBM +//OPsaveDstack begin + /GroupPushed //false def + /ChangeBM //false def + /saveOA 1 def + /saveSA 1 def + /saveBM /Normal def + /previous 1 dict def % for nested setup_trans levels +end + +/Dpush { + .currentglobal //true .setglobal % 'previous' dict must be in global VM + //OPsaveDstack 6 dict 1 index { 2 index 3 1 roll put } forall /previous exch put + .setglobal +} def +/Dpop { //OPsaveDstack begin previous { def } forall end } def % colorspaces that don't require special overprint transparency handling /okOPcs mark /DeviceGray 0 /DeviceCMYK 1 /DeviceN 2 /Separation 3 .dicttomark def -/checkOPtrans % <fillop|strokeop> checkOPtrans <bool> -% return true if OP needs special transparency treatment -% If the colorspace is not one where overprint makes sense, no special handling (return false) -% NB: This will get replaced with a quick "no-op" if the device doesn't support Overprint +% Take care of pushing a transparency group if we need it for SMask or for Overprint.. +% After pushing the group, we save the opacityalpha and shapealpha and change them +% both to 1. For overprint if the colorspace is acceptable, also change to +% CompatibleOverprint if the device needs it. + +% NB: setup_trans is defined as either setupOPtrans (for devices that can support +% overprint, or as setupSMtrans which pushes a group for SMask. +% Also see 'teardown_trans' that pops the group and resets the changed values. +/setupOPtrans % <fillop|strokeop> setup_trans { % Check OP and BM in case we need to push a group - okOPcs currentcolorspace 0 get dup /Indexed eq { - pop currentcolorspace 1 get % use the base space - } if - known { - /stroke ne { .currentfilloverprint - } { .currentstrokeoverprint - } ifelse - .currentblendmode dup /Normal eq exch /Compatible eq or not and - } { - pop //false - } ifelse + //OPsaveDstack begin + //Dpush exec % push the current OPsaveDstack values into 'previous' + okOPcs currentcolorspace 0 get dup /Indexed eq { + pop currentcolorspace 1 get % use the base space + } if + known { + 1 index /stroke ne { .currentfilloverprint } { .currentstrokeoverprint } ifelse + % Change BM to CompatibleOverprint if this has overprint true + dup /ChangeBM exch def + .currentblendmode dup /Normal eq exch /Compatible eq or + not and + } { + //false + } ifelse + .currentSMask //null ne or { % push a group for OP or SMask + mark /Subtype /Group /Isolated .currentSMask //null ne .dicttomark + 1 index /stroke eq { + % BBox needs to include line width / line join expansion. + gsave strokepath pathbbox grestore + } { + pathbbox % fill/eofill cases + } ifelse + .begintransparencygroup + % After group pushed, set opacityalpha, shapealpha and blendmode + /saveOA .currentopacityalpha def + /saveSA .currentshapealpha def + 1 .setopacityalpha 1 .setshapealpha + /GroupPushed //true def + } if + % we may change to CompatibleOverprint even if we didn't push a group. + ChangeBM { + /saveBM .currentblendmode def /CompatibleOverprint .setblendmode + } if + pop % fillop/strokeop + end % OPsaveDstack +} bind executeonly def + +% Also see 'teardown_trans' that pops the group and resets the changed values. +/setupSMtrans % <fillop|strokeop> setup_trans +{ + //OPsaveDstack begin + //Dpush exec % push the current OPsaveDstack values into 'previous' + .currentSMask //null ne 1 index /image ne and % only push for SMask if not from image + { + mark /Subtype /Group /Isolated //true .dicttomark + exch /stroke eq { + % BBox needs to include line width / line join expansion. + gsave strokepath pathbbox grestore + } { + pathbbox % fill/eofill cases + } ifelse + .begintransparencygroup + % After group pushed, set opacityalpha, shapealpha and blendmode + /saveOA .currentopacityalpha def + /saveSA .currentshapealpha def + 1 .setopacityalpha 1 .setshapealpha + /GroupPushed //true def + } { + /GroupPushed //false def + pop % fillop/strokeop + } ifelse + end % OPsaveDstack +} bind executeonly def + +% If a transparency group was pushed, pop it, and reset the settings. +% Used after setup_trans +/teardown_trans { + //OPsaveDstack begin + GroupPushed { + % pop the group, then restore the opacityalpha and shapealpha + .endtransparencygroup % end the group + saveOA .setopacityalpha saveSA .setshapealpha + } if + % Also, if we changed the BM, restore it (AFTER the group was popped) + .currentblendmode /CompatibleOverprint eq { + % restore the blendmode + saveBM .setblendmode + } if + end % OPsaveDstack + //Dpop exec % load previous OPsaveDstack contents } bind executeonly def +currentdict dup /Dpush .undef /Dpop .undef + +% ------------------------------------------------------------ % /fsexec % <fillop|strokeop> fsexec - { PDFusingtransparency { - .currentSMask //null ne { - mark /Subtype /Group /Isolated //true .dicttomark - 1 index /stroke eq { - % BBox needs to include line width / line join expansion. - gsave strokepath pathbbox grestore - } { - pathbbox % fill/eofill cases - } ifelse - .begintransparencygroup - .currentshapealpha .currentopacityalpha 3 -1 roll % avoid double application - 1 .setopacityalpha 1 .setshapealpha - } if - dup checkOPtrans exch 1 index { - % We need to push a non-isolated, non-knockout transparency group and - % perform the operation in CompatibleOverprint mode, then end the - % transparency group. Do the begintransparencygroup step here. - mark /Subtype /Group /Isolated //false .dicttomark pathbbox .begintransparencygroup - .currentblendmode .currentopacityalpha 4 -2 roll % save current values - /CompatibleOverprint .setblendmode 1 .setopacityalpha - } if + dup setup_trans cvx exec - { - .endtransparencygroup .setopacityalpha .setblendmode % end the CompatibleOverprint group - } if - .currentSMask //null ne { - .endtransparencygroup .setopacityalpha .setshapealpha - } if + teardown_trans } { cvx exec } ifelse @@ -1098,11 +1173,13 @@ end readonly def } bind executeonly odef /BT { + //false /illegal_BT gput currentdict /TextSaveMatrix known { ( **** Error: illegal nested BT operator detected.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror ET_NO_TXT_KO %% Does not push any compositor actions + //true /illegal_BT gput } if %% Bug #695897 see the explanation in /q defined above. @@ -1112,6 +1189,7 @@ end readonly def pdfformaterror ( Output may be incorrect.\n) pdfformaterror ET_NO_TXT_KO %% Does not push any compositor actions + //true /illegal_BT gput } if currentdict /n known { currentdict end @@ -1133,7 +1211,9 @@ end readonly def %% If needed, let the pdf14 device know we are in a BT condition. This %% distinguishes BT from an Annotation /FreeText show command which also %% can come into pdf_text_begin with an opacity not equal to 1. - PDFusingtransparency .currenttextknockout and { + PDFusingtransparency .currenttextknockout and + currentdict /illegal_BT get not and +{ .begintransparencytextgroup } if @@ -1141,8 +1221,8 @@ end readonly def /ET_NO_TXT_KO { currentdict /TextSaveMatrix known { - .currenttextrenderingmode 4 ge { .currentfilladjust2 0 dup .setfilladjust2 clip .setfilladjust2} if - newpath TextSaveMatrix setmatrix + .currenttextrenderingmode 4 ge { .currentfilladjust2 0 dup .setfilladjust2 clip .setfilladjust2 newpath} if + TextSaveMatrix setmatrix currentdict /TextSaveMatrix undef % if we were in a W/W* context, grab the dict, undefine temp entry for it, @@ -1560,37 +1640,14 @@ end readonly def } bind executeonly def % If current path is not known to be valid, use the clip path -/TextTransSetup { % showarg path_valid TextTransSetup false showarg - % showarg path_valid false TextTransSetup prev_BM prev_opacity true showarg +/TextTransSetup { % showarg path_valid TextTransSetup showarg + % showarg path_valid false TextTransSetup showarg % NB: if 'show' is used, then we use the clippath, but a smaller bbox is preferred - .currentSMask //null ne { - dup mark /Subtype /Group /Isolated //true .dicttomark exch - { pathbbox } { gsave clippath pathbbox grestore } ifelse - .begintransparencygroup - } if - //null checkOPtrans { - % We need to push a non-isolated, non-knockout transparency group and - % perform the operation in CompatibleOverprint mode, then end the - % transparency group. Do the begintransparencygroup step here. - mark /Subtype /Group /Isolated //false .dicttomark exch - { pathbbox } { gsave clippath pathbbox grestore } ifelse - .begintransparencygroup - OPsavedict dup /saveBM .currentblendmode put /saveOA .currentopacityalpha put % save current values - /CompatibleOverprint .setblendmode 1 .setopacityalpha - } { - pop % discard path_valid boolean - } ifelse + not dup { gsave clippath } if //null setup_trans { grestore } if } bind executeonly def -/TextTransTeardown { % stack: path_valid - .currentblendmode /CompatibleOverprint eq { - % end the CompatibleOverprint group and restore the opacity and BM - .endtransparencygroup - OPsavedict dup /saveOA get .setopacityalpha /saveBM get .setblendmode - } if - .currentSMask //null ne { - .endtransparencygroup - } if +/TextTransTeardown { + teardown_trans } bind executeonly def /setshowstate @@ -2008,7 +2065,46 @@ end readonly def 8 { pop } repeat } { 5 index 16#1000000 and 0 ne { % comb - 8 { pop } repeat (Combed form fields are not yet implemented.) = + 6 index type /stringtype eq { + 6 index length 0 gt { + 6 index length 8 index % length of V and MaxLength + gt { + (Comb field with /V string which exceeds /MaxLength. Ignoring field.) = + 8 {pop} repeat + }{ + 3 index 8 index div % field Rect width / MaxLength, the offset between 'comb' boxes + 7 index + <EFBBBF> anchorsearch { + pop + } { + <FEFF> anchorsearch { + pop + } if + } ifelse + { + currentpoint newpath moveto % new path, preserving currnt point + currentpoint % store the current point, this is the origin for the next 'comb' + 3 -1 roll 1 string dup 3 -1 roll exch 0 3 -1 roll put % turn the character code into a 1 byte string + dup gsave + false charpath flattenpath pathbbox grestore % get the bounding box of that character + 3 -1 roll sub 3 1 roll exch sub % get its width and height (ch, cw) + 8 index 6 index % comb box width and height (bh, bw) + 3 -1 roll % ch cw bh bw -> ch bh bw cw + sub 2 div % ch bh (bw - cw) / 2 = ch bh dw + 3 1 roll % ch bh dw -> dw ch bh + exch sub 2 div % dw (bh - ch) /2 = dw dh + rmoveto % centers character in box + Show exch 2 index add exch moveto % Draw the character + } forall % repeat for every character in the original string + 9 {pop} repeat % discard the various arguments + }ifelse + }{ + 8 {pop} repeat % discard the parameters + }ifelse + }{ + (Comb field with a non-string /V value is illegal. Ignoring field.) = + 8 {pop} repeat + } ifelse } { % plain text 3 1 roll sub add 2 div % MaxLen (V) Ff Q dx (dy-yy+desc)/2 0 exch moveto % MaxLen (V) Ff Q dx diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_rbld.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_rbld.ps index 3aca13d8cb9..b018c5c73ae 100644 --- a/Master/tlpkg/tlgs/Resource/Init/pdf_rbld.ps +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_rbld.ps @@ -260,13 +260,26 @@ % 'startxref' loc = end loc - remaing string length - 9 bytes length sub 9 sub % move the file to this position and read startxref and position + % First, read the startxref token, this should not fail. PDFfile exch setfileposition PDFfile token - pop pop PDFfile token_no_close pop - dup type /integertype eq not { - pop - % startxref not followed by integer. We will search the end of the file for trailer. + { + % Discard the startxref token and read the following token, which should be the offset. + pop PDFfile token_no_close + { + % Now chck its an integer + dup type /integertype eq not { + pop + % startxref not followed by integer. We will search the end of the file for trailer. + PDFfilelen + } if + } { + % startxref not followed by any token. We will search the end of the file for trailer. + PDFfilelen + } ifelse + } { + % No startxref token ? We will search the end of the file for trailer. PDFfilelen - } if + } ifelse } { % startxref not found. We will search the end of the file for trailer. pop pop PDFfilelen |