From fda5435ca272bab86872d2627667b5b259eb5423 Mon Sep 17 00:00:00 2001 From: Reinhard Kotucha Date: Thu, 5 Oct 2017 20:49:39 +0000 Subject: Upgrade gs-9.21 -> gs-9.22 git-svn-id: svn://tug.org/texlive/trunk@45477 c570f23f-e606-0410-a88d-b1316a301751 --- Master/tlpkg/tlgs/Resource/IdiomSet/Pscript5Idiom | 4 +- Master/tlpkg/tlgs/Resource/Init/gs_cet.ps | 2 +- Master/tlpkg/tlgs/Resource/Init/gs_dps1.ps | 7 +- Master/tlpkg/tlgs/Resource/Init/gs_fonts.ps | 6 +- Master/tlpkg/tlgs/Resource/Init/gs_img.ps | 115 ---- Master/tlpkg/tlgs/Resource/Init/gs_ll3.ps | 2 +- Master/tlpkg/tlgs/Resource/Init/gs_statd.ps | 2 +- Master/tlpkg/tlgs/Resource/Init/gs_ttf.ps | 78 ++- Master/tlpkg/tlgs/Resource/Init/gs_type1.ps | 4 +- Master/tlpkg/tlgs/Resource/Init/pdf_base.ps | 27 +- Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps | 644 +++++++++++++++++----- Master/tlpkg/tlgs/Resource/Init/pdf_font.ps | 148 +++-- Master/tlpkg/tlgs/Resource/Init/pdf_main.ps | 403 +++++++++++--- Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps | 574 +++++++++++-------- 14 files changed, 1353 insertions(+), 663 deletions(-) (limited to 'Master/tlpkg/tlgs/Resource') diff --git a/Master/tlpkg/tlgs/Resource/IdiomSet/Pscript5Idiom b/Master/tlpkg/tlgs/Resource/IdiomSet/Pscript5Idiom index e22a946e593..021603f3341 100644 --- a/Master/tlpkg/tlgs/Resource/IdiomSet/Pscript5Idiom +++ b/Master/tlpkg/tlgs/Resource/IdiomSet/Pscript5Idiom @@ -137,8 +137,8 @@ currentuserparams /IdiomRecognition get /Decode[0 1]def}{/Decode[0 1 0 1 0 1 0 1]def}ifelse}ifelse/DataSource{PaintData}def end/ImageDict exch def/PaintProc{begin ImageDict image end}b currentdict mx makepattern setpattern end fEOFill{eofill}{fill} ifelse grestore - } - } + } ifelse + }bind ] /mask_pbf [ diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_cet.ps b/Master/tlpkg/tlgs/Resource/Init/gs_cet.ps index 8eb79bb06e0..d3e1686409b 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_cet.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_cet.ps @@ -21,7 +21,7 @@ currentglobal //true setglobal /serialnumber dup {233640} readonly .makeoperator put % match CPSI 3017.102 Tek shows serialnumber 1401788461 systemdict /deviceinfo undef % for CET 20-23-1 % /UNROLLFORMS true put % CET files do unreasonable things inside forms -} superexec +} 1183615869 internaldict /superexec get exec /UNROLLFORMS true def diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_dps1.ps b/Master/tlpkg/tlgs/Resource/Init/gs_dps1.ps index a57bb94ed3b..a4d6dda2a5c 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_dps1.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_dps1.ps @@ -55,8 +55,7 @@ level2dict begin { //SharedFontDirectory } { /LocalFontDirectory .systemvar } % can't embed ref to local VM ifelse .forceput pop % LocalFontDirectory is local, systemdict is global - } .bind odef % must bind .forceput and .setglobal - % even if NOBIND in effect + } .bind odef % Don't just copy (load) the definition of .setglobal: % it gets redefined for LL3. /setshared { /.setglobal .systemvar exec } odef @@ -86,7 +85,7 @@ level2dict begin % definition, copy it into the local directory. //systemdict /SharedFontDirectory .knownget { 1 index .knownget - { .FontDirectory 2 index 3 -1 roll { put } //superexec } % readonly + { .FontDirectory 2 index 3 -1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } % readonly if } if @@ -102,7 +101,7 @@ level2dict begin % Furthermore, if FAKEFONTS is in effect, we want global real fonts to % override fake local ones. We handle this by brute force. /restore % restore - - { dup //restore % bind even if NOBIND + { dup //restore /LocalFontDirectory .systemvar FAKEFONTS { mark diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_fonts.ps b/Master/tlpkg/tlgs/Resource/Init/gs_fonts.ps index a3da615cb3f..1f4c9eda288 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_fonts.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_fonts.ps @@ -519,11 +519,11 @@ buildfontdict 3 /.buildfont3 cvx put % the font in LocalFontDirectory. .currentglobal { //systemdict /LocalFontDirectory .knownget - { 2 index 2 index { .growput } //superexec } % readonly + { 2 index 2 index { .growput } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } % readonly if } if - dup .FontDirectory 4 -2 roll { .growput } //superexec % readonly + dup .FontDirectory 4 -2 roll { .growput } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse % readonly % If the font originated as a resource, register it. currentfile .currentresourcefile eq { dup .registerfont } if readonly @@ -1193,7 +1193,7 @@ currentdict /.putgstringcopy .undef .FontDirectory 1 index known not { 2 dict dup /FontName 3 index put dup /FontType 1 put - .FontDirectory 3 1 roll { put } //superexec % readonly + .FontDirectory 3 1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse % readonly } { pop } ifelse diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_img.ps b/Master/tlpkg/tlgs/Resource/Init/gs_img.ps index f2b0f6287da..e1cd6279323 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_img.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_img.ps @@ -746,119 +746,4 @@ if end % img_utils_dict -% Conditionally turn image interpolation on or off. -% INTERPOLATE is not yet set, handle all cases -currentdict /INTERPOLATE known -currentdict /DOTERPOLATE known or -currentdict /NOTERPOLATE known or not { - currentfile 1 (%END INTERPOLATE) .subfiledecode flushfile -} if - -/.interpolate { - dup /Interpolate .knownget not { //false } if - /INTERPOLATE .systemvar ne { - dup gcheck .currentglobal exch .setglobal - exch dup length dict copy - dup /Interpolate /INTERPOLATE .systemvar put - exch .setglobal - } if -} .bind odef - -/colorimage - { /INTERPOLATE .systemvar - { .currentglobal % w h bit [] {}...{} multi ncomp glob - //false .setglobal - 9 dict begin % w h bit [] {}...{} multi ncomp glob - 2 .argindex { 1 index 7 add } { 8 } ifelse - dup .argindex pop % check # of arguments - copy gsave pop % preserve the arguments - { 0 /DeviceGray 0 /DeviceRGB /DeviceCMYK } - 1 index get setcolorspace % ... glob w h bit [] {}...{} multi ncomp - {0 1 0 1 0 1 0 1} - 1 index 2 mul 0 exch % ... glob w h bit [] {}...{} multi ncomp {0 1 ...} 0 2*ncomp - getinterval /Decode exch def % ... glob w h bit [] {}...{} multi ncomp - exch dup % ... glob w h bit [] {}...{} ncomp multi multi - /MultipleDataSources exch def % ... glob w h bit [] {}...{} ncomp multi - { array astore} { pop } ifelse % ... glob w h bit [] [{}...{}] - /DataSource exch def % ... glob w h bit [] - /ImageMatrix exch def % ... glob w h bit - /BitsPerComponent exch def % ... glob w h - /Height exch def % ... glob w - /Width exch def % ... glob - /ImageType 1 def - /Interpolate //true def - .setglobal currentdict end % ... <<>> - image grestore - exch { 4 add } { 6 } ifelse - { pop } repeat % - - } - { colorimage - } - ifelse - } .bind odef - -/image - { dup type /dicttype eq - { dup /ImageType get 3 eq - { .currentglobal //false .setglobal exch - dup length dict copy begin .setglobal - /DataDict DataDict .interpolate def - /MaskDict MaskDict .interpolate def - currentdict end - } - { .interpolate - } - ifelse - image - } - { /INTERPOLATE .systemvar - { 4 .argindex pop % check # of args - .currentglobal //false .setglobal - 8 dict begin .setglobal - /ImageType 1 def - /DataSource 1 index def - /ImageMatrix 2 index def - /BitsPerComponent 3 index def - /Decode {0 1} def - /Height 4 index def - /Width 5 index def - /Interpolate //true def - currentdict end - gsave /DeviceGray setcolorspace image grestore - 5 { pop } repeat - } - { image - } - ifelse - } - ifelse - } .bind odef - -/imagemask { - dup type /dicttype eq { - .interpolate imagemask - } { - /INTERPOLATE .systemvar { - 4 .argindex pop % check # of args - .currentglobal //false .setglobal - 8 dict begin .setglobal - /ImageType 1 def - /DataSource 1 index def - /ImageMatrix 2 index def - /BitsPerComponent 1 def - 2 index { {1 0} } { {0 1} } ifelse /Decode exch def - /Height 4 index def - /Width 5 index def - /Interpolate //true def - currentdict end imagemask 5 { pop } repeat - } { - imagemask - } ifelse - } ifelse -} .bind odef - -currentdict /.interpolate .undef - -%END INTERPOLATE - .setglobal % restore VM mode diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_ll3.ps b/Master/tlpkg/tlgs/Resource/Init/gs_ll3.ps index a1deb5891a4..e2bffba377e 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_ll3.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_ll3.ps @@ -58,7 +58,7 @@ languagelevel dup 2 .max .setlanguagelevel /.bind /.bind_ load odef % note that .bind_ will get bound currentdict /.bindscratch .undef -DELAYBIND NOBIND or not { +DELAYBIND not { % We can't just do % /bind /.bind load def % because then /bind load == prints --.bind-- . diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_statd.ps b/Master/tlpkg/tlgs/Resource/Init/gs_statd.ps index 18dfced1499..dbcf05199c9 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_statd.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_statd.ps @@ -59,7 +59,7 @@ statusdict begin % shrunk by 25 units on all 4 sides. /note /letter load def % End of Adobe-defined page sizes -STRICT { (%END SIZES) .skipeof } if + % Other page sizes % ISO standard paper sizes /a0 {2384 3370 //.setpagesize exec} bind def diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_ttf.ps b/Master/tlpkg/tlgs/Resource/Init/gs_ttf.ps index ebacc6bbd0d..8cb5b390c57 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_ttf.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_ttf.ps @@ -435,7 +435,7 @@ currentdict /woff_tag_dict .undef } bind def % Each procedure in this dictionary is called as follows: -% proc +% proc /cmapformats mark 0 { % Apple standard 1-to-1 mapping. 6 256 getinterval_from_stringarray @@ -538,35 +538,20 @@ currentdict /woff_tag_dict .undef /putglyph { glyphs code 3 -1 roll put /code code 1 add def } bind def - % Do a first pass to compute the size of the glyphs array. - /numcodes 0 def /glyphs 0 dict def - 0 0 2 nseg2 3 sub { - % Stack: /glyphs numglyphs i2 - /i2 exch def - /scode startc i2 getu16a def - /ecode endc i2 getu16a def - - % Bug 693538: More undocumented nonsense: in cases where scode == ecode, - % see Bug 691326 below *except*, it seems when both are zero - scode 0 eq ecode 0 eq and not { - scode ecode 1 add gt { % Bug 691326. - /ecode scode 1 add def % Acrobat does this contrary to TTF spec that - } if % requires such intervals to be ignored. - 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 ecode scode sub 1 add add - exch 1 index add exch - numcodes add /numcodes exch def - } if - } for pop - - % Now fill in the array. /numcodes 0 def /code 0 def - 0 2 nseg2 3 sub { + % 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 + % codes being 0xffff. Unfortunately, we have found badly subsetted + % TTF fonts which have one segment with valid mappings, and no + % closing segment. + % In such a case, force the loop to work as though as we have two + % 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. + 0 2 nseg2 dup 4 lt {pop 4}if 3 sub { /i2 exch def /scode startc i2 getu16a def /ecode endc i2 getu16a def @@ -633,8 +618,8 @@ currentdict /woff_tag_dict .undef } bind .dicttomark readonly def % cmapformats -% cmaparray -/cmaparray { +% cmapdict +/cmapdict { dup 0 getu16a cmapformats exch .knownget { TTFDEBUG { (cmap: format ) print 1 index 0 getu16a = flush @@ -1389,7 +1374,7 @@ mark def } if - /cmapa cmaptab cmaparray def + /cmapa cmaptab cmapdict def % Some badly designed Chinese fonts have a post table % in which all glyphs other than 0 are named .null. % Use CharStrings to keep track of the reverse map from @@ -1436,7 +1421,7 @@ mark TTFDEBUG { (\n1 setting alias: ) print dup ==only ( to be the same as ) print 2 index //== exec } if - 7 index 2 index 3 -1 roll exch //.growput superexec + 7 index 2 index 3 -1 roll exch //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } forall pop pop pop } @@ -1454,7 +1439,7 @@ mark exch pop TTFDEBUG { (\n2 setting alias: ) print 1 index ==only ( to use glyph index: ) print dup //== exec } if - 5 index 3 1 roll //.growput superexec + 5 index 3 1 roll //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse //false } { @@ -1471,7 +1456,7 @@ mark { % CharStrings(dict) isunicode(boolean) cmap(dict) RAGL(dict) gname(name) codep(integer) gindex(integer) TTFDEBUG { (\3 nsetting alias: ) print 1 index ==only ( to be index: ) print dup //== exec } if - exch pop 5 index 3 1 roll //.growput superexec + exch pop 5 index 3 1 roll //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } { pop pop @@ -1626,7 +1611,7 @@ currentdict /postalias undef mark .ttkeys /NumGlyphs numloca - /TT_cmap cmaptab cmaparray + /TT_cmap cmaptab cmapdict /file_table_pos file_table_pos /Decoding Decoding .dicttomark @@ -1645,7 +1630,7 @@ currentdict /postalias undef mark .ttkeys /NumGlyphs numloca - /TT_cmap cmaptab cmaparray + /TT_cmap cmaptab cmapdict % /file_table_pos file_table_pos /Decoding Decoding .dicttomark @@ -1767,9 +1752,8 @@ currentdict /postalias undef % .pdfmapchars /CharStrings /.pdfmapchars { - exch cmaparray /cmapencoding exch def % c2g + exch cmapdict /cmapencoding exch def % c2g /CharStrings 0 dict % c2g /CS <<>> - % Add glyphs of * : 3 2 roll { % /CS <<>> v dup type /arraytype eq { % /CS <<>> /name [] @@ -1806,13 +1790,12 @@ currentdict /postalias undef } forall dup /.notdef 0 put - } bind def % .pdfmapsymbolic /Encoding [] /CharStrings <<>> /.pdfmapsymbolic { //true /.render_notdef gput - cmaparray + cmapdict dup length 1 add dict begin [ 64 { /.notdef /.notdef /.notdef /.notdef } repeat ] exch { % [] char glyph @@ -1845,7 +1828,7 @@ currentdict /postalias undef % The following algorithms are per the PDF 1.7 Reference. TTFDEBUG { (.pdfcharkeys beg) = } if - % if the flags say symbolic, *and* the font contains a symbol + % if the flags say symbolic, *and* the font contains a symbol or UCS-2 % cmap table, ignore Encoding if there is one, treat as symbolic. % If the flags say symbolic, and the font doesn't have a symbol cmap % and we have an Encoding, treat it as non-symbolic @@ -1853,7 +1836,20 @@ currentdict /postalias undef % Finally, if none of that works, remove the Encoding, and treat it % as non-symbolic. is_symbolic { - <00030000> .findcmap { //true } { prebuilt_encoding //null eq { <00010000> .findcmap}{//false}ifelse } ifelse { + <00030000> .findcmap + { //true } + { + prebuilt_encoding //null eq { + <00030001> .findcmap + {//true} + {<00010000> .findcmap} + ifelse + } + {//false} + ifelse + } ifelse + + { .pdfmapsymbolic /prebuilt_encoding //null def //false diff --git a/Master/tlpkg/tlgs/Resource/Init/gs_type1.ps b/Master/tlpkg/tlgs/Resource/Init/gs_type1.ps index 772bb7163ff..dbd9bf38a44 100644 --- a/Master/tlpkg/tlgs/Resource/Init/gs_type1.ps +++ b/Master/tlpkg/tlgs/Resource/Init/gs_type1.ps @@ -116,7 +116,7 @@ { % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname aglname CFFDEBUG { (\nsetting alias: ) print dup ==only ( to be the same as glyph: ) print 1 index //== exec } if - 3 index exch 3 index //.growput superexec + 3 index exch 3 index //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname } {pop} ifelse @@ -135,7 +135,7 @@ 3 1 roll pop pop } if pop - dup /.AGLprocessed~GS //true //.growput superexec + dup /.AGLprocessed~GS //true //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } if %% We need to excute the C .buildfont1 in a stopped context so that, if there diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_base.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_base.ps index bdfe9ee8feb..f2ae2dec3ef 100644 --- a/Master/tlpkg/tlgs/Resource/Init/pdf_base.ps +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_base.ps @@ -774,6 +774,11 @@ currentdict /no_debug_dict undef % When resolving an object reference, we stop at the endobj or endstream. /resolveopdict mark valueopdict { } forall + /xref { % Bug 697761 + ( **** Error: Encountered 'xref' while expecting 'endobj'.\n) pdfformaterror + ( Treating this as a missing 'endobj', output may be incorrect.\n) pdfformaterror + endobj exit + } bind /endstream { endobj exit } bind /endobj { endobj exit } bind /endjobj { % Bug 689876. @@ -786,9 +791,13 @@ currentdict /no_debug_dict undef ( Output may be incorrect.\n) pdfformaterror endobj exit } bind + /obj { % OmniForm generates PDF file with endobj missing in some % objects. AR ignores this. So we have to do it too. - /obj { pop pop endobj exit } bind + ( **** Error: Encountered 'obj' while expecting 'endobj'.\n) pdfformaterror + ( Treating this as a missing 'endobj', output may be incorrect.\n) pdfformaterror + pop pop endobj exit + } bind .dicttomark readonly def /resolveR { % resolveR @@ -849,12 +858,13 @@ currentdict /no_debug_dict undef dup type /dicttype eq % For dictionaries only { - dup /Type .knownget % make sure the dictionary has a type + dup /Type known % make sure the dictionary has a type { - dup /Font eq exch /FontDescriptor eq or % and ensure its a Font or FontDescriptor - {dup 3 -1 roll /.gs.pdfobj# exch put} - {exch pop} - ifelse + %% We must not add to *all* dictionaries, because some of them are handled by + %% executing all the key/value pairs, and adding a integer causes problems + %% Since we only use this number for font identification, or checking self-references, + %% we only need it for dictionaries with a Type, and these are always handled more carefully. + dup 3 -1 roll /.gs.pdfobj# exch put } {exch pop} ifelse @@ -889,11 +899,6 @@ currentdict /no_debug_dict undef % may have preceded the EOL, such as spaces or tabs. Thus we back up one % character and scan until we find the \n terminator. /stream { % stream - dup /Length knownoget { - 0 eq { - dup /Filter undef % don't confuse any filters that require data - } if - } if dup /F known dup PDFsource PDFfile eq or { not { dup /File PDFfile put diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps index 88da2de7485..68a56a3674b 100644 --- a/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_draw.ps @@ -26,34 +26,6 @@ pdfdict begin % PDF graphics operations, even though this is too liberal. /drawopdict 100 dict def -/SetGroupExtGStateDict -<< - /AlphaIsShape //AIS - /FillConstantAlpha //ca - % We don't have to worry about the enumeration order, even - % with the color/space settings, since we only store, not - % not set them. - /FillColor //sc1 - /FillColorSpace { /FillColorSpace gput } bind - /FillOverprint //op - /SoftMask //SMask - /StrokeConstantAlpha //CA - /StrokeColor //SC1 - /StrokeColorSpace { /StrokeColorSpace gput } bind - /StrokeOverprint //OP - /TextSpacing //Tc - % We can't use //Tz as we've stored the value we actually use, - % not value * 100 (see /Tz in pdf_ops.ps) - /TextHScaling { /TextHScaling gput } bind - /Leading //TD - /TextFont { /TextFont gput} bind - /TextLineMatrix { /TextLineMatrix gput } bind - /TextMatrix { /TextMatrix gput } bind - /TextRise { /TextRise gput } bind - /TextRenderingMode { /TextRenderingMode gput } bind - /WordSpacing //Tw ->> def - % ================================ Graphics ================================ % % ---------------- Functions ---------------- % @@ -156,6 +128,20 @@ pdfdict begin 1 index /Default eq { exch pop } { pop resolveidfnproc } ifelse } bdef +%% A BBox where width or height (or both) is 0 should still paint one pixel +%% See the ISO 32000-2:2017 spec, section 8.7.4.3, p228 'BBox' and 8.7.3.1 +/FixPatternBBox +{ + dup aload pop + 3 index 2 index sub 0 eq { + 3 index 0.000001 add 3 -1 roll pop exch + } if + 2 index 1 index sub 0 eq { + 2 index 0.000001 add exch pop + }if + 5 -1 roll astore +}bind def + % ---------------- Shadings ---------------- % /shrdict mark @@ -177,6 +163,7 @@ pdfdict begin /BBox { dup dup dup aload pop normrect_elems 5 -1 roll astore + FixPatternBBox } bind /ColorSpace { resolvecolorspace @@ -472,6 +459,13 @@ end /AIS { AIS } /BM { BM } /TK { TK } + /UseBlackPtComp { UseBlackPtComp } + /HTO { + % PDF 2.0, supposed to be 'similar' to halftone phase but using a different + % co-ordiate system. Treat the same for now and fix if anyone ever complains. + aload pop transform cvi exch cvi exch 2 array astore + dup sethalftonephases .swapcolors sethalftonephases .swapcolors + } .dicttomark readonly def /gs { % gs - Page /ExtGState rget { @@ -502,7 +496,8 @@ end dup /None eq 1 index //null eq or PDFusingtransparency not or { pop //null - SoftMask //null ne { + + .currentSMask //null ne { % get rid of the current SMask (Bug 695471) false % colorspace not set << /Subtype /None >> % Special type for this purpose @@ -558,18 +553,9 @@ end /GroupGState gstate currentgstate 6 2 roll grestore /GroupMat matrix currentmatrix 8 2 roll - /GroupExtGState 1 dict - //SetGroupExtGStateDict - { - exch dup where - { - exch get 2 index 3 1 roll put - } - { - pop pop - } ifelse - } forall - 10 2 roll +% /GroupExtGState 1 dict +% 10 2 roll + /.execmaskgroup cvx 2 packedarray cvx /Draw exch 3 2 roll pop .dicttomark @@ -634,48 +620,62 @@ def 3 -1 roll dup dup 4 1 roll /BBox get aload pop .begintransparencymaskgroup exch dup /Resources knownoget { oforce } { 2 dict } ifelse - 3 -1 roll dup /GroupGState .knownget { 2 index /GroupGState 3 -1 roll put} if - /GroupExtGState .knownget { 1 index /GroupExtGState 3 -1 roll put} if + 3 -1 roll /GroupGState .knownget { 1 index /GroupGState 3 -1 roll put} if exch //false resolvestream - 1 index exch .execgroup + 1 index exch + + %% Get the current colour space and colour values (as an array), we need to pass these to .execgroup + %% as well, so that it can restore them, in case the colour space gets changed by transparency + %% graphics state stuff. + mark currentcolor counttomark array astore exch pop + currentcolorspace 4 2 roll + + .execgroup % We have to remove these in case the Form XObject is subsequently used as % a form rather than a group - they remain in the paramdict for the SMask % so this will all still work if the SMask is re-evaluated. - dup /GroupGState undef - /GroupExtGState undef + /GroupGState undef + .endtransparencymask PDFfile exch setfileposition mark exch /OverrideICC exch .dicttomark setuserparams .setuseciecolor setcolorspace setcolor setmatrix end % restore colorspace, color and ExtGState (end) - /SoftMask where pop /SoftMask //true put % special setting to tell us it has been rendered + .currentSMask /Processed //true put % special setting to tell us it has been rendered } bdef % Paint a Form+Group XObject, either for a transparency mask or for a Do. -/.execgroup { % .execgroup - +/.execgroup { % [colour values] .execgroup - pdfemptycount 3 1 roll - /pdfemptycount count 3 sub store + /pdfemptycount count 5 sub store gsave //nodict begin % We have to set the gstate correctly for lazy evaluation of a softmask group. - % we also must preserve the color(space) as setup in .execmaskgroup. + % we also must restore the color(space) as setup in .execmaskgroup or paintformgroup. % This stuff must be done here, as .execmaskgroup can't use gsave/grestore to % manipulate the gstates, due to the requirements of .begintransparencymaskgroup. % We also must set the ExtGState values. % It may seem redundant to do the color(space) twice (once here and once in % .execmaskgroup) but we have to set it in .execmaskgroup for the background % color and set it here once in the correct gstate. - mark currentcolor currentcolorspace counttomark 2 add index dup + 1 index /GroupGState .knownget { setgstate } if - /GroupExtGState .knownget { { exch exec } forall } if - setcolorspace setcolor pop + newpath //null SMask 1 .setopacityalpha 1 .setshapealpha 1 CA 1 ca /Compatible .setblendmode % Execute the body of the Form, similar to DoForm. - pdfopdict .pdfruncontext + pdfopdict + + %% Restore the colour space (passed in on the stack) and current colour + %% + 6 -2 roll + setcolorspace + aload pop setcolor + + .pdfruncontext end grestore /pdfemptycount exch store } bdef @@ -694,6 +694,11 @@ def % .paintgroupform implements the Form PaintProc in the case where the % Form XObject dictionary includes a Group key. See .paintform below. /.paintgroupform { % .paintgroupform - + %% Pass the current color space, and an array with the current color vales + %% as arguments to .execgroup + mark currentcolor counttomark array astore exch pop + currentcolorspace 5 2 roll + dup /Group oget exch /BBox oget % Stack: resdict stream groupdict bbox .beginformgroup @@ -730,7 +735,8 @@ def DataDict /Matte knownoget { /Matte exch def } if - AlphaIsShape { /ShapeMaskDict } { /OpacityMaskDict } ifelse exch def + .currentalphaisshape + { /ShapeMaskDict } { /OpacityMaskDict } ifelse exch def /ColorSpace DataDict /ColorSpace get def } bdef @@ -1055,13 +1061,16 @@ currentdict end readonly def } { % For uncolored patterns, we have to unbind the current % color and color space before running the PaintProc. - //null sc1 //null SC1 + % Not true since moving the ExtGState parameters into the gstate. + % //null sc1 //null SC1 } ifelse % Save old values on opstack, set pdfemptycount to new value. pdfemptycount countdictstack mark - /pdfemptycount count 3 sub def 5 3 roll + %% We can't simply 'def' into the dictionary saved by 'q' above, we need to + %% call gput to copy it and store inside it. Stupid or what.... + /pdfemptycount count 3 sub gput 5 3 roll % % Stack: ... mark % | @@ -1074,11 +1083,51 @@ currentdict end readonly def { countdictstack 2 index le { exit } if currentdict /n known not or - Q - } loop { - ( **** Error: Pattern stream has unbalanced q/Q operators \(too many q's\)\n) - pdfformaterror - ( Output may be incorrect.\n) pdfformaterror + currentdict /n known currentdict /self known or{ + Q + }{ + (\n **** Error: File has unbalanced q/Q operators \(too many Q's\)\n Output may be incorrect.\n) + pdfdict /.Qqwarning_issued .knownget + { + { + pop + } + { + currentglobal pdfdict gcheck .setglobal + pdfdict /.Qqwarning_issued //true .forceput + .setglobal + pdfformaterror + } ifelse + } + { + currentglobal pdfdict gcheck .setglobal + pdfdict /.Qqwarning_issued //true .forceput + .setglobal + pdfformaterror + } ifelse + end + } ifelse + } loop + { + (\n **** Error: File has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n) + pdfdict /.Qqwarning_issued .knownget + { + { + pop + } + { + currentglobal pdfdict gcheck .setglobal + pdfdict /.Qqwarning_issued //true .forceput + .setglobal + pdfformaterror + } ifelse + } + { + currentglobal pdfdict gcheck .setglobal + pdfdict /.Qqwarning_issued //true .forceput + .setglobal + pdfformaterror + } ifelse } if pop @@ -1150,7 +1199,7 @@ currentdict end readonly def 2 index /Resources knownoget { oforce } { 0 dict } ifelse /.pdfpaintproc cvx ] cvx put - dup /BBox 2 copy knownoget { normrect put } { pop pop } ifelse + dup /BBox 2 copy knownoget { normrect FixPatternBBox put } { pop pop } ifelse dup /.pattern_uses_transparency 1 index patternusestransparency put PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Pattern: ) print dup === flush } if } if } bdef @@ -1189,7 +1238,12 @@ drawopdict begin /sc { .incachedevice { .pdfcount { pop } repeat //ignore_color_op pdfformaterror } { - scresolve { sc*_and_set } { sc1_and_set } ifelse + scresolve 1 index //null eq { + pop pop + //ignore_color_op pdfformaterror + } { + { sc*_and_set } { sc1_and_set } ifelse + } ifelse } ifelse } bdef @@ -1233,7 +1287,12 @@ drawopdict begin /SC { .incachedevice { .pdfcount { pop } repeat //ignore_color_op pdfformaterror } { - scresolve { SC*_and_set } { SC1_and_set } ifelse + scresolve 1 index //null eq { + pop pop + //ignore_color_op pdfformaterror + }{ + { SC*_and_set } { SC1_and_set } ifelse + }ifelse } ifelse } bdef @@ -1300,7 +1359,7 @@ drawopdict begin setfillstate resolvesh //sh_save 0 save put PDFusingtransparency { - SoftMask //null ne { + .currentSMask //null ne { //sh_group 1 index /BBox knownoget { { oforce } forall @@ -1327,7 +1386,7 @@ drawopdict begin { .endtransparencygroup .setopacityalpha .setblendmode % end the CompatibleOverprint group } if - SoftMask //null ne { + .currentSMask //null ne { .endtransparencygroup } if } { @@ -1359,7 +1418,7 @@ end /CIEBasedABC { 1 get /RangeABC knownoget not { //01_3 } if } bind /CalGray { pop //01_1 } bind /CalRGB { pop //01_3 } bind - /Lab { 1 get /Range knownoget not { [-100 100 -100 100] } if } bind + /Lab { 1 get /Range knownoget not { [-100 100 -100 100] } {aload pop 0 100 6 2 roll 6 array astore}ifelse } bind /ICCBased { 1 oget dup /Range knownoget { exch pop @@ -2024,7 +2083,7 @@ currentdict /last-ditch-bpc-csp undef ColorSpace dup type /arraytype eq { 0 oget } if /Indexed eq BitsPerComponent 1 eq and { - % AR9 treats Indexed 1 bpc images specially. Bug 692852. + % 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 { % First component is invalid - AR9 ignores the mask @@ -2037,7 +2096,33 @@ currentdict /last-ditch-bpc-csp undef % AR5, AR9 do this for most cases. Bug 690786. [ exch { 1 BitsPerComponent bitshift 1 sub and } forall ] } ifelse - } if + } { + 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 + }{ + dup 0 1 put + } ifelse + } if + }{ + % AR5, AR9 do this for most cases. Bug 690786. + [ exch { 1 BitsPerComponent bitshift 1 sub and } forall ] + } ifelse + } ifelse dup //null ne { /MaskColor exch def } { @@ -2089,7 +2174,7 @@ currentdict /last-ditch-bpc-csp undef .begintransparencymaskimage PDFfile fileposition exch gsave //nodict begin - //null /SoftMask gput + //null .setSMask 1 .setopacityalpha 1 .setshapealpha 1 CA 1 ca /Compatible .setblendmode @@ -2109,7 +2194,7 @@ currentdict /last-ditch-bpc-csp undef % on our lazy evaulation of SMask groups false << /Subtype /None >> 0 0 0 0 .begintransparencymaskgroup } { - SoftMask //null ne { + .currentSMask //null ne { % the image doesn't have an SMask, but the ExtGState does, force a group. << /Subtype /Group /Isolated //true >> 0 0 1 1 .begintransparencygroup doimage @@ -2128,6 +2213,44 @@ currentdict /last-ditch-bpc-csp undef } bdef } if +/ValidateDecode { % <> -imagemask- ValidateDecode <> + exch + dup /Decode .knownget { + dup length % -imagemask- <> [Decode] length + 4 -1 roll % <> [Decode] length -imagemask- + { + 1 % ImageMask Decode arrays must be [0 1] or [1 0] + } + { + mark currentcolor counttomark % <> [Decode] length [ ... component_count + dup 2 add 1 roll % <> [Decode] length component_count [ .... + cleartomark % <> [Decode] length component_count + } ifelse + 2 mul dup % <> [Decode] length comp_count*2 comp_count*2 + 3 1 roll % <> [Decode] comp_count*2 length comp_count*2 + eq { % <> length of Decode matches colour space requirement + pop pop % <> remove [Decode] and comp_count*2 + }{ % <> Decode array incorrect + dup 2 index length % <> [Decode] comp_count*2 comp_count*2 length + exch sub 0 gt { % Decode is too long + (\n **** Warning: Decode array for an image is too long\n) pdfformatwarning + ( Output may be incorrect.\n) pdfformatwarning + 0 exch % <> [Decode] 0 comp_count*2 + getinterval % <> [subarray of Decode] + 1 index exch /Decode exch % <> <> /Decode [subarray] + put % <> + }{ + % Decode is too short, Acrobat throws errors on this + (\n **** ERROR: Decode array for an image is too short\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + pop pop % remove [Decode] and comp_count*2 + } ifelse + } ifelse + } { + exch pop + }ifelse +}bdef + /doimage { % doimage - % imagedict is currentdict, gets popped from dstack //null checkOPtrans { @@ -2160,8 +2283,8 @@ currentdict /last-ditch-bpc-csp undef makemaskimage } if % Stack: datasource imagemask - { currentdict end setfillstate { imagemask } } - { ColorSpace setgcolorspace currentdict end setfillblend { image } } + { currentdict end setfillstate true ValidateDecode { imagemask } } + { ColorSpace setgcolorspace currentdict end setfillblend false ValidateDecode { image } } ifelse PDFSTOPONERROR { exec //false } { stopped } ifelse { dup type /dicttype eq { pop } if % Sometimes image fails to restore the stack @@ -2451,7 +2574,61 @@ currentdict end readonly def //ocg_pocs exch get exec % bool } ifelse } { - /OFF known not % OFF is inserted by process_trailer_attrs + dup /OFF known not % OFF is inserted by process_trailer_attrs + { + %% /OC is not in the OCProperties /OFF array, so we need to + %% test its usage. We may eventually have to add a /ON to the dictionary + %% if the OCProperties /ON array defines the /OC, I think that should override + % the Usage, but I don't have an example to test. + /Usage .knownget { + oforce + /Printed where { + /Printed get + } { + //false + }ifelse + { + %% We are behaving as a printer, check the Print state + /Print .knownget { + /PrintState .knownget { + oforce + /OFF eq { + //false + }{ + //true + } ifelse + }{ + //true + } ifelse + }{ + %% If we don't know, assume its visible + //true + } ifelse + }{ + %% We are behaving as a viewer, check the View state + /View .knownget { + oforce + /ViewState .knownget { + /OFF eq { + //false + }{ + //true + } ifelse + }{ + //true + } ifelse + }{ + %% If we don't know, assume its visible + //true + } ifelse + } ifelse + }{ + %% If we don't know, assume its visible + //true + } ifelse + }{ + pop //false + }ifelse } ifelse } { /OFF known not % OFF is inserted by process_trailer_attrs @@ -2480,30 +2657,72 @@ drawopdict begin } if setfillblend PDFfile fileposition exch % pos /Name - dup Page /XObject rget { - exch pop % pos obj - OFFlevels length 0 eq { - dup /OC knownoget { ocg-is-visible } { //true } ifelse - } { + + % Bug #698226, Acrobat signals an error for recursive XObjects in a PDF file + % but continues. This is true even if the XObject is not a simple self-reference + % (eg /Fm1 -> /Fm2 -> /Fm3 -> /Fm1). + % Normally when dealing with recursion we would put a dictionary on the stack, store the + % object numbers encoutnered in it, and check each new object number to see if we've + % already seen it. This doesn't work well for XObjects, because the operand stack can be + % in any state when we run a Do. So we make a new dictionary in pdfdict to hold the + % object numbers. + % We also don't usually know the object number of a Form, we just get given its name + % so we need a new routine to return the object number. This is because the parent XObject + % might reference teh object by one name, while the child references it by another, we + % can't permit clashes. + % + % Start by getting the object number for a Form XObject + dup Page /XObject obj_get dup 0 eq not { + % Now get the recording dictionary and see if that object number has been seen + pdfdict /Recursive_XObject_D get 1 index known { + ( **** Error: Recursive XObject detected, ignoring ") print 1 index 256 string cvs print (", object number ) print 256 string cvs print (\n) print + ( Output may be incorrect.\n) pdfformaterror //false - } ifelse { - dup /Subtype oget //xobjectprocs exch get % pos obj {proc} - % Don't leave extra objects on the stack while executing - % the definition of the form. - 3 -1 roll % obj {proc} pos - 2 .execn % pos + }{ + % We haven't seen it yet, so record it. + pdfdict /Recursive_XObject_D get 1 index null put + 3 1 roll + //true + }ifelse + } + { + % I don't think this should be possible, but just in case + ( **** Error: Unable to determine object number for ) print exch 256 string cvs print ( so ignoring it) print + ( Output may be incorrect.\n) pdfformaterror + //false + } ifelse + + % If we could get the object number, and we haven't already seen it, then execute it. + { + dup Page /XObject rget { + exch pop % pos obj + OFFlevels length 0 eq { + dup /OC knownoget { ocg-is-visible } { //true } ifelse + } { + //false + } ifelse { + dup /Subtype oget //xobjectprocs exch get % pos obj {proc} + % Don't leave extra objects on the stack while executing + % the definition of the form. + 3 -1 roll % obj {proc} pos + 2 .execn % pos + } { + pop % pos + } ifelse } { - pop % pos + % This should cause an error, but Acrobat Reader can + % continue, so we do too. + ( **** Error: Undefined XObject resource: ) + exch =string cvs concatstrings (\n) concatstrings + pdfformaterror + ( Output may be incorrect.\n) pdfformaterror } ifelse - } { - % This should cause an error, but Acrobat Reader can - % continue, so we do too. - ( **** Error: Undefined XObject resource: ) - exch =string cvs concatstrings (\n) concatstrings - pdfformaterror - ( Output may be incorrect.\n) pdfformaterror + PDFfile exch setfileposition + pdfdict /Recursive_XObject_D get exch undef + }{ + % Otherwise ignore it and tidy up the stacks + pop pop } ifelse - PDFfile exch setfileposition } bdef end @@ -2854,11 +3073,15 @@ end dup (BT ) writestring 1 index /DA fget not { 1 index /V fget { - anchorsearch{ - pop pop /FallBackFont /Identity-UTF16-H [/CIDFallBack] composefont 12 scalefont setfont - }{ + anchorsearch { pop /Helvetica findfont 12 scalefont setfont - } ifelse + } { + anchorsearch { + pop pop /FallBackFont /Identity-UTF16-H [/CIDFallBack] composefont 12 scalefont setfont + } { + pop /Helvetica findfont 12 scalefont setfont + }ifelse + }ifelse } if () }if @@ -2894,11 +3117,18 @@ end //false exch NeedAppearances { dup /FT fget { - /Tx eq { - dup /V oknown { - pop not 1 - } if - } if + dup /Tx eq { + pop + dup /V oknown { + pop not 1 + } if + } { + /Ch eq { + dup /V oknown { + pop not 1 + } if + } if + } ifelse } if } if pop @@ -2920,6 +3150,7 @@ end % dup /AP undef % } if % } if + dup /AP knownoget { dup /N known not { ( **** Error: Appearance dictionary (AP) lacks the mandatory normal (N) appearance.\n) @@ -3264,6 +3495,12 @@ currentdict /set_bc_color undef /emptydict 0 dict readonly def /Highlight { +% technically we should apply an appearance stream if we have one, but if we do +% some test files don't match Acrobat. PDF 2.0 says appearance streams are mandatory, +% and take precedence over generatig new ones, so we may need to revisit this. +% dup /AP oknown { +% //true +% }{ 0 setlinecap dup annotsetcolor { /QuadPoints knownoget { @@ -3287,6 +3524,7 @@ currentdict /set_bc_color undef } if } if //false +% } ifelse } bdef currentdict /emptydict undef currentdict /highlight-arc undef @@ -3402,7 +3640,7 @@ currentdict /set_bc_color undef { gsave - dup annotrect (rectclip from freetext annotation) == flush rectclip + dup annotrect rectclip dup /CA knownoget { .setopacityalpha @@ -3684,7 +3922,7 @@ currentdict /set_bc_color undef 2 index 2 div add exch 3 index 2 div add exch translate % dx dy - 50 div exch 190 div .min dup scale + 50 div exch 190 div .min dup 0.0 eq {pop 1.0} if dup scale /Name knownoget not { /Draft } if //stamp_dict 1 index known not { exch pop /Draft exch } if @@ -3700,24 +3938,124 @@ currentdict /set_bc_color undef } ifelse } bdef - currentdict /quadpoints2basis undef + /Popup { + dup /Open oknown { + dup /Open get { + dup /AP oknown { + //true + }{ + gsave + newpath + 0.05 setlinewidth + dup /Parent .knownget { + oforce + } { + dup /P .knownget { + oforce + } { + dup + } ifelse + } ifelse + /C .knownget { + aload pop + }{ + 1 1 0 + }ifelse + setrgbcolor + dup /Rect get + dup aload pop + 2 index sub + exch 3 index sub exch + 4 copy + gsave 1 setgray rectfill grestore + gsave 0 setgray rectstroke grestore + 1 index /Parent .knownget { + oforce + }{ + 1 index /P .knownget { + oforce + }{ + 1 index + } ifelse + }ifelse + dup + /Contents .knownget { + gsave + 0 setgray + /Helvetica findfont 9 scalefont setfont + 2 index aload pop 3 1 roll pop pop 30 sub exch 5 add exch + moveto show + grestore + } if + exch + dup aload pop 3 -1 roll pop exch 2 index sub -15 + 4 copy rectfill + 0 setgray rectstroke + exch + /T .knownget { + gsave + 0 setgray + /Helvetica findfont 9 scalefont setfont + dup stringwidth pop + 2 index aload pop pop exch pop exch sub + exch sub 2 div 2 index aload pop 3 1 roll pop pop 11 sub 3 1 roll add exch moveto + show + grestore + } if + grestore + //false + } ifelse + } { + pop //false + }ifelse + } { + pop //false + }ifelse + } bdef + +currentdict /quadpoints2basis undef currentdict end readonly def +/.PDFDrawAnnotType? +{ + //false exch + /ShowAnnotTypes where + { + /ShowAnnotTypes get + { + dup /* eq exch 2 index eq or + { + pop //true exch + exit + } if + } forall + pop + } + {pop pop //true} + ifelse +} bind def + /drawannot { % drawannot - dup annotvisible { gsave dup dup /Subtype knownoget { - //drawannottypes exch .knownget { exec } { //true } ifelse + dup //.PDFDrawAnnotType? exec { - dup calc_annot_scale 2 copy mul 0 ne - { - 3 -1 roll drawwidget - } + //drawannottypes exch .knownget { exec } { //true } ifelse { - ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror - ( Output may be incorrect.\n) pdfformaterror - }ifelse % Draw rejected annots as widgets - } if % type known + dup calc_annot_scale 2 copy mul 0 ne + { + 3 -1 roll drawwidget + } + { + ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror + ( Output may be incorrect.\n) pdfformaterror + }ifelse % Draw rejected annots as widgets + } if % type known + } + { + pop + }ifelse } { pop ( **** Error: Ignoring /Annot dict without required /Subtype entry.\n) @@ -3909,17 +4247,22 @@ currentdict end readonly def dup annotvisible { gsave dup dup /Subtype knownoget { - //preserveannottypes exch .knownget { exec } { //true } ifelse + dup //.PDFDrawAnnotType? exec { - dup calc_annot_scale 2 copy mul 0 ne - { - 3 -1 roll drawwidget - } + //preserveannottypes exch .knownget { exec } { //true } ifelse { - ( **** Error: ignoring annotation with scale factor of 0\n) pdfformaterror - ( Output may be incorrect.\n) pdfformaterror - }ifelse % Draw rejected annots as widgets - } if % type known + dup calc_annot_scale 2 copy mul 0 ne + { + 3 -1 roll drawwidget + } + { + ( **** 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) @@ -3931,6 +4274,7 @@ currentdict end readonly def } bdef currentdict /preserveannottypes undef +currentdict /.PDFDrawAnnotType? undef % ============================ AcroForm fields ============================ % @@ -4013,8 +4357,8 @@ currentdict /preserveannottypes undef { 1 index exch write== } forall dup 3 index /MaxLen pget not { 0 } if write= dup 3 index /V pget not { - 3 index /DV pget not { () } if write== - } if + 3 index /DV pget not { () } if + } if write== dup 3 index /Ff pget not { 0 } if write= dup 3 index /Q pget not { 0 } if write= dup (Tform ET) write= @@ -4026,7 +4370,51 @@ currentdict /preserveannottypes undef } bdef /Ch { - (Ch is not yet implemened) //== exec + dup /AP known 3 index /NeedAppearances knownoget not { //true } if not and { + dup 1 1 3 -1 roll drawwidget + } { + %% If we don't have a NeedApperances, treat as true, because Acrobat + %% always regenerates Appearances anyway. + 2 index /NeedAppearances knownoget not { //true } if { + dup /AP << /N 10 dict dup cvx begin >> put + /Subtype /Form def + /BBox [ 0 0 4 index /Rect oget { oforce } forall 3 -1 roll sub abs 3 1 roll sub abs exch ] def + /Resources 3 index /DR pget not { 0 dict } if def + /File 1000 string dup 3 1 roll def + /Length 1000 def + % (string) + /NullEncode filter % file + + dup (BT ) writestring + 2 index /DA pget not { () } if + [ exch + { token { + dup /Tf eq { + 2 index 0 eq { + /BBox load 3 get + 0.75 mul % empirical constant + 4 -1 roll pop 3 1 roll + } if + } if + exch + } { + exit + } ifelse + } loop + ] + { 1 index exch write== } forall + dup 3 index /MaxLen pget not { 0 } if write= + dup 3 index /V pget not { + 3 index /DV pget not { () } if + } if write== + dup 3 index /Ff pget not { 0 } if write= + dup 3 index /Q pget not { 0 } if write= + dup (Tform ET) write= + end + closefile % + dup 1 1 3 -1 roll drawwidget + } if + } ifelse } bdef /Sig { diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps index 7060dbce6f0..02a3b0f6602 100644 --- a/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_font.ps @@ -268,7 +268,6 @@ currentdict /known_symbolic_fonts undef /getfontmetrics { % getfontmetrics % % - 2 index /Widths oknown { dup //null eq { pop dup /Encoding get } if 7 dict begin @@ -871,7 +870,9 @@ setglobal { 0 1 2 index length 1 sub { - dup 2 index exch get dup 0 gt % We ignore entries of zero in the widths array + dup 2 index exch get + dup type /packedarraytype eq {exec} if % Handle entries which are indirect references (seriously ? !!) + dup 0 gt % We ignore entries of zero in the widths array { exch 5 index add % add FirstChar to the idx to get a char code dup 64 gt 1 index 91 lt and % we only want to consider A~Z and.... @@ -986,48 +987,62 @@ setglobal .dicttomark readonly def % When Type 1 font reading procedure is executing, a copy of this dictionary is current. -% We have to do something special about embedded fonts that execute definefont -% more than once -- that is the function of topFontDict. +% topFontDict allows us to *attempt* to handle the case where a Type 1 font definition +% does not start by creating it's own dictionary (i.e. a number of the keys end up in +% the currentdict rather than the font dictionary). % The whole type1 stream can be executed directly. There's no need to process % Length1, 2, 3 keys. /readtype1dict 10 dict dup begin - /definefont { - exch pop + /prev_definefont /definefont load def - /topFontDict where { - { /FontType % in PLRM order - /FontMatrix - /FontName - /FontInfo - /WMode - /Encoding - /FontBBox - /UniqueID - /XUID - /PaintType - /StrokeWidth - /Metrics - /Metrics2 - /CDevProc - /CharStrings - /Private - /WeightVector - } { - 2 copy .knownget { - % Stack: font topFontDict /key val - 3 index 3 1 roll put + /definefont { + % if a font defines any keys outside it's own dictionary, + % this attempts to cope by copying them into the font dictionary + [ + /FontType % in PLRM order + /FontMatrix + /FontName + /FontInfo + /WMode + /Encoding + /FontBBox + /UniqueID + /XUID + /PaintType + /StrokeWidth + /Metrics + /Metrics2 + /CDevProc + /CharStrings + /Private + /WeightVector + ] + { + 2 copy known + {pop} + { + dup where + { + 1 index get + 2 index + 3 1 roll put dup /MisplacedKey 0 put - } { - pop - } ifelse - } forall - /MisplacedKey known { - ( **** Warning: Type 1 font defines some of the keys in the external scope.\n) - pdfformatwarning - } if + } + {pop} ifelse + } ifelse + } forall + dup /MisplacedKey known { + ( **** Warning: Type 1 font defines some required keys outside the font dictionary.\n) + pdfformatwarning } if + dup /CharStrings get /.notdef known not { + dup /CharStrings get + /.notdef <9E35CED7FFD3622F09> put + ( **** Warning: Type 1 font has no /.notdef entry in /CharString dictionary.\n) + pdfformatwarning + } if dup /UniqueID .knownget { dup dup 0 lt exch 16#ffffff gt or { ( **** Warning: Ignoring invalid /UniqueID = ) exch =string cvs @@ -1037,17 +1052,11 @@ setglobal pop } ifelse } if - dup /CharStrings get /.notdef known not { - dup /CharStrings get - /.notdef <9E35CED7FFD3622F09> put - ( **** Warning: Type 1 font has no /.notdef entry in /CharString dictionary.\n) - pdfformatwarning - } if - .completefont + prev_definefont } bdef /undef_proc_warning { - /Repaired //true store % flag that we have warnings + /Repaired //true store % flag that we have warnings UndefProcList exch 2 copy .knownget { 1 add } { 1 } ifelse put } bdef @@ -1182,18 +1191,48 @@ currentdict /eexec_pdf_param_dict .undef % the character code to access the Widths. /BuildChar { % Stack: font charcode - 1 index begin 3 dict begin + 1 index begin 4 dict begin /Font 3 -1 roll def /CharCode 1 index def Encoding exch get CharProcs exch knownoget { - { //false resolvestream + dup /Length get 0 eq { + pop + %% Detect a 0 length stream. If this occurs + %% then we won't execute d0 or d1, and so won't adjust the + %% character width. So, pretend we got a + %% null d1, just so that we can adjust using the /Widths + %% (Bug 697805) + 0 0 0 0 0 0 + pdfopdict /d1 get exec + }{ + { //false resolvestream % Stack: filepos stream % Don't let setgcolor set the color inside the BuildGlyph % procedure, because this causes an /undefined error. - q //null /FillColor gput //null /StrokeColor gput - Font /Resources get exch pdfopdict .pdfruncontext - Q - } PDFfile fileposition 2 .execn % Keep pdfcount valid. - PDFfile exch setfileposition + q + %% This is (currently) needed to make sure that the current dictionary, which is + %% 'nodict' because we did a gsave, is writeable. If we don't execute gput + %% to make a writeable copy then it is a no access dicitonary and the 'def' + %% below will fail. It would be nice to fix the cases of this someday, but + %% we use 'nodict'[ to store other PDF state stuff that isn't gstate, and we + %% probably always will, so it may well be more trouble than its worth. + /Dummy false gput + Font /Resources get exch pdfopdict + /BuildCharDictDepth countdictstack def + .pdfruncontext + countdictstack BuildCharDictDepth sub + { + pdfdict /.Qqwarning_issued .knownget {not}{//true} ifelse + { + (\n **** Warning: Type 3 glyph has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n) + pdfformatwarning + pdfdict /.Qqwarning_issued //true .forceput + } if + Q + } repeat + Q + } PDFfile fileposition 2 .execn % Keep pdfcount valid. + PDFfile exch setfileposition + } ifelse } { % PDF Type 3 fonts don't use .notdef % d1 implementation adjusts the width as needed @@ -2282,12 +2321,7 @@ currentdict /bndef undef % in multipage documents. /patch_font_XUID % patch_font_XUID { - %% Allow users to specify that we should not care about font object numbers - %% that is, don't patch the XUID with the object number and filename. - /PDFDontUseFontObjectNum where {/PDFDontUseFontObjectNum get}{//false}ifelse - %% Do not modify the XUID if we don't have an object number (see above) - 1 index //null eq - or + dup //null eq {pop} { pdfdict /InputPDFFileName .knownget {.CRCHashFilenameAndObject} if diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps index 85b5848e160..a16f5806734 100644 --- a/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps @@ -85,6 +85,9 @@ pdfdict begin pdfformaterror ( Output may be incorrect.\n) pdfformaterror } bind + + /Recursive_XObject_D 1 dict def + .dicttomark readonly def % ======================== Main program ======================== % @@ -948,9 +951,17 @@ currentdict /xref-char-dict undef %% Bug #695883 the test file has an XRefStm which points beyond the end of the file. %% We check that here and simply fall back to thje classic xref if this error occurs. dup PDFfilelen lt{ - readpdf15xref pop + PDFSTOPONERROR not { + mark exch {readpdf15xref pop} stopped + { + ( **** Error: This hybrid file's XRefStm does not point to a valid stream.\n Ignoring error, output may be incorrect.\n) pdfformaterror + } if + cleartomark + } { + readpdf15xref pop + } ifelse } { - ( **** Error: This hybrid file's XRefStm points beyond the end of file.\n Ignoring error, output may be incorrect.\n) pdfformaterror + ( **** Error: This hybrid file's XRefStm points beyond the end of file.\n Ignoring error, output may be incorrect.\n) pdfformaterror pop }ifelse } if @@ -1129,7 +1140,37 @@ currentdict /xref-char-dict undef ( **** ) stderrprint stderrprint } ifelse } ifelse - } if + } { + % If the user told us to use a named OutputIntent + systemdict /UseOutputIntent .knownget { + cvn + Trailer /Root oget /OutputIntents knownoget { + { + dup /OutputConditionIdentifier get cvn + dup /Custom eq { + pop + dup /Info get cvn + }if + 2 index eq { + %% Found the required OutputIntent + /DestOutputProfile knownoget { + [ /ICCBased 3 -1 roll ] ICCBased-resolve + 1 get .set_outputintent + () + } if + pop + exit + }{ + pop + } ifelse + } + forall + pop + }{ + pop + }ifelse + } if + }ifelse Trailer /Root knownoget { /PageLabels knownoget { %% Currenlty only the pdfwrite device can handle PageLabels %% because we deal with these using putparams, not pdfmarks @@ -1283,6 +1324,8 @@ currentdict /xref-char-dict undef % Read any previous cross-reference tables. When we are done, % verify that the entries in the xref tables are valid if NoVerifyXref % is not defined. + /PrevArray [] def % Empty array, we use this to detect circular /Prev entries in xref (see below) + % For some reqason, leaving this on the stack messes up seom files. Trailer { /Prev knownoget not { % If no previous xref table then ... Classic-xref { @@ -1290,10 +1333,43 @@ currentdict /xref-char-dict undef } if exit } if + + %% This code is used to detect circular references in xref tables. Every time + %% we detect a /Prev in the xref, we check the given offset of the /Prev xref + %% against a list of all previously encountered /Prev offsets. If we find that + %% we have previously seen this one, we raise an error, stop processing the xref + %% but carry on with the PDF file (unless PDFSTOPONERROR is true). + //false exch PrevArray %% Used to determine if the looop found a circular ref + { %% //false offset 'array entry' + 1 index eq { + exch pop //true exch %% We've seen this offset before, pop the false and replace with true + exit %% //true offset + } if + } forall + + exch %% [...] offset bool + { + (\n **** Error: Circular /Prev entry while reading xref.\n Aborting xref read, output may be incorrect.\n) + pdfformaterror + PDFSTOPONERROR { + /readxref /syntaxerror cvx signalerror + } if + pop exit %% [...] and then exit this loop + } if + + PrevArray dup %% offset [...] [...] + length 1 add array %% offset [...] [ ] + dup 3 1 roll %% offset [ ] [...] [ ] + copy pop %% offset [... ] + dup dup length 1 sub %% offset [... ] [... ] index + 3 index %% offset [... ] [... ] index offset + put /PrevArray exch def + { readxref } PDFSTOPONERROR not { .internalstopped { recover_xref_data % Read failed. Attempt to recover xref data. + /PrevArray where {/PrevArray undef} if %% remove the array we were using to detect circular references exit % Exit loop since recover gets all obj data. } if % If readxref stopped } { @@ -1312,6 +1388,7 @@ currentdict /xref-char-dict undef } ifelse } forall } loop % Loop to previous trailer + /PrevArray where {/PrevArray undef} if %% remove the array we were using to detect circular references } if /NumObjects Objects length def % To check that obj# < NumObjects @@ -1584,10 +1661,32 @@ currentdict /xref-char-dict undef { 2 copy knownoget { exch pop exch pop //true } - { exch /Parent knownoget - { exch pget } + { + %% Check to see if there's a Parent + 1 index + 3 1 roll + exch /Parent knownoget + { + %% If there is a Parent, check to see if this dictionary has a stored object number + 3 -1 roll /.gs.pdfobj# .knownget { + %% if it does, check the Parent as wwell + 1 index /.gs.pdfobj# .knownget { + %% Both have object numbers, are they the same (ie its self-referencing) + eq { + pop pop + //false + }{ + exch pget + }ifelse + }{ + pop exch pget + }ifelse + } { + exch pget + }ifelse + } % finally see if the key is (misplaced) in the Root Catalog dict - { dup Trailer /Root oget exch knownoget dup { + { exch pop dup Trailer /Root oget exch knownoget dup { 3 -1 roll ( **** Error: The /) pdfformaterror 50 string cvs pdfformaterror ( key is missing from the Page tree.\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror @@ -1600,6 +1699,30 @@ currentdict /xref-char-dict undef ifelse } bind def +/obj_get { + LocalResources 1 index knownoget { + dup 4 index known { + 3 index get + 0 get 4 1 roll pop pop pop + } if + } { + 1 index /Resources pget { + 1 index knownoget { + dup 4 index known { + 3 index get + 0 get 4 1 roll pop pop pop + }{ + pop pop pop 0 + }ifelse + }{ + pop pop pop 0 + } ifelse + } { + pop pop pop 0 + }ifelse + }ifelse +}bind def + % Get the value of a resource on a given page. /rget { % rget -true- % rget -false- @@ -2109,14 +2232,61 @@ end readonly def /MediaBox exch get_media_box pop } { oforce_elems % <> /SomeBox x0 y0 x1 y1 + %% Complicated stuff. We need to use the 'Box' we identified (if any), but we + %% need to clamp the boundaries of the 'Box' to the MediaBox. This appears to + %% be what Acrobat does. The complication arises because the Box values don't + %% have to be sensibly positive, its permissible to have the MediaBox set up + %% so that it extends down and left instead of up and right. We take care of the + %% content when we st up the CTM, but we do need to make sure that we clamp + %% the BoundingBox, and that means we need to take direcitonality into account... + 6 -1 roll get_media_box { % /SomeBox x0 y0 x1 y1 [MediaBox] aload pop % /SomeBox x0 y0 x1 y1 X0 Y0 X1 Y1 - 5 -1 roll .min exch % /SomeBox x0 y0 x1 X0 Y0 mY1 X1 - 5 -1 roll .min exch % /SomeBox x0 y0 X0 Y0 mX1 mY1 - 4 2 roll % /SomeBox x0 y0 mX1 mY1 X0 Y0 - 5 -1 roll .max exch % /SomeBox x0 mX1 mY1 mY0 X0 - 5 -1 roll .max exch % /SomeBox mX1 mY1 mX0 mY0 - 4 2 roll % /SomeBox mX0 mY0 mX1 mY1 + + %% Start with the width, get the X0 and X1 values of the MediaBox + 3 index % /SomeBox x0 y0 x1 y1 X0 Y0 X1 Y1 X0 + 2 index % /SomeBox x0 y0 x1 y1 X0 Y0 X1 Y1 X0 X1 + gt { + %% Media extends to left + 4 -1 roll % /SomeBox x0 y0 x1 y1 Y0 X1 Y1 X0 + 8 -1 roll % /SomeBox y0 x1 y1 Y0 X1 Y1 X0 x0 + .min % /SomeBox y0 x1 y1 Y0 X1 Y1 mX0 + 7 1 roll % /SomeBox mX0 y0 x1 y1 Y0 X1 Y1 + exch % /SomeBox mX0 y0 x1 y1 Y0 Y1 X1 + 5 -1 roll % /SomeBox mX0 y0 y1 Y0 Y1 X1 x1 + .max % /SomeBox mX0 y0 y1 Y0 Y1 mX1 + 5 1 roll % /SomeBox mX0 mX1 y0 y1 Y0 Y1 + }{ + %% Media extends to right + 4 -1 roll % /SomeBox x0 y0 x1 y1 Y0 X1 Y1 X0 + 8 -1 roll % /SomeBox y0 x1 y1 Y0 X1 Y1 X0 x0 + .max % /SomeBox y0 x1 y1 Y0 X1 Y1 mX0 + 7 1 roll % /SomeBox mX0 y0 x1 y1 Y0 X1 Y1 + exch % /SomeBox mX0 y0 x1 y1 Y0 Y1 X1 + 5 -1 roll % /SomeBox mX0 y0 y1 Y0 Y1 X1 x1 + .min % /SomeBox mX0 y0 y1 Y0 Y1 mX1 + 5 1 roll % /SomeBox mX0 mX1 y0 y1 Y0 Y1 + } ifelse + + %% Now deal with the height + 2 copy % /SomeBox mX0 mX1 y0 y1 Y0 Y1 Y0 Y1 + gt { + %% Media extends down + exch % /SomeBox mX0 mX1 y0 y1 Y1 Y0 + 4 -1 roll % /SomeBox mX0 mX1 y1 Y1 Y0 y0 + .min % /SomeBox mX0 mX1 y1 Y1 mY0 + 3 1 roll % /SomeBox mX0 mX1 mY0 y1 Y1 + .max % /SomeBox mX0 mX1 mY0 mY1 + }{ + %% Media extends up + exch % /SomeBox mX0 mX1 y0 y1 Y1 Y0 + 4 -1 roll % /SomeBox mX0 mX1 y1 Y1 Y0 y0 + .max % /SomeBox mX0 mX1 y1 Y1 mY0 + 3 1 roll % /SomeBox mX0 mX1 mY0 y1 Y1 + .min % /SomeBox mX0 mX1 mY0 mY1 + } ifelse + exch % /SomeBox mX0 mX1 mY1 mY0 + 3 1 roll % /SomeBox mX0 mY0 mX1 mY1 } { pop } ifelse @@ -2268,6 +2438,37 @@ currentdict /PDF2PS_matrix_key undef % is not actually used on the page. currentpagedevice /PageSpotColors known { /PageSpotColors 2 index countspotcolors def } if + % If the user told us to use a named OutputIntent + systemdict /UseOutputIntent .knownget { + cvn + % Check to see if this page has such an OutputIntent + 2 index /OutputIntents knownoget { + { + dup /OutputConditionIdentifier get cvn + dup /Custom eq { + pop + dup /Info get cvn + }if + 2 index eq { + %% Found the required OutputIntent + /DestOutputProfile knownoget { + [ /ICCBased 3 -1 roll ] ICCBased-resolve + 1 get .set_outputintent + () + } if + pop + exit + }{ + pop + } ifelse + } + forall + pop + }{ + pop + }ifelse + } if + % Let the device know if we will be using PDF 1.4 transparency. % The clist logic may need to adjust the size of bands. 1 index pageusestransparency /PageUsesTransparency exch def @@ -2541,7 +2742,22 @@ currentdict /PDF2PS_matrix_key undef } { dup //false exch { 4 dict 1 index resourceusestransparency { pop not exit } if - /Parent knownoget not { exit } if + %% Check the current dictionary and its Parent (if any) to see + %% if they both have stored object numbers. If they do then + %% check the numbers, don't allow self-references. + dup /Parent knownoget not { pop exit } + { + exch /.gs.pdfobj# .knownget + { + 1 index /.gs.pdfobj# .knownget { + eq { + pop exit + }if + }{ + pop + }ifelse + }if + } ifelse } loop % Also check for transparency in the annotation (if not in resources). { pop //true } { annotsusetransparency } ifelse @@ -2884,74 +3100,87 @@ currentdict /PDF2PS_matrix_key undef } if } bind def -%% pdfform_detect_cspacesub +%% pdfform_detect_cspacesub %% /pdf_object_detect_cspacesub { - exch %% - dup pdf_colorspace_detect_cspacesub { - pop //true - }{ %% - /Resources knownoget { %% - /XObject knownoget { %% - //false exch %% false - %% We have files where the XObject Resource is not a dictionary - dup type /dicttype eq { %% false - - %% check each Xobject entry in the dictionary, - %% forall purs a key/value pair on the stack for us. - %% - { %% false key value - exch pop %% false value - - %% If this is an indirect reference, check if its the smae object - %% as the current one. If its not indirect, make the object number 0 - %% for comparison purposes. - dup type /packedarraytype eq { - dup 0 get dup 4 index - eq - } { - 0 false - }ifelse + %% use loop operator for an exitable context + %% we need this to detect recursion/looping + { + exch %% + dup pdf_colorspace_detect_cspacesub { + pop pop //true exit + }{ %% + /Resources knownoget { %% + 2 index 1 index known { + %% We've already seen this object, ignore it and exit + pop pop //false exit + }{ + 2 index 1 index //null put + } ifelse - %% false value
- not { - %% swap object number and value, and dereference value - exch oforce - %% Apparently we have files where the content of the XObject Resource dictionary is null - dup //null ne { - %% and files where the indivudal XObjects are not dictionaries - dup type /dicttype eq { - dup /Subtype get /Form eq { - exch - pdf_object_detect_cspacesub { - pop //true exit - } if - } { + /XObject knownoget { %% + //false exch %% false + %% We have files where the XObject Resource is not a dictionary + dup type /dicttype eq { %% false + + %% check each Xobject entry in the dictionary, + %% forall purs a key/value pair on the stack for us. + %% + { %% false key value + exch pop %% false value + + %% If this is an indirect reference, check if its the smae object + %% as the current one. If its not indirect, make the object number 0 + %% for comparison purposes. + dup type /packedarraytype eq { + dup 0 get dup 4 index + eq + } { + 0 false + }ifelse + + %% false value + not { + %% swap object number and value, and dereference value + exch oforce + %% Apparently we have files where the content of the XObject Resource dictionary is null + dup //null ne { + %% and files where the indivudal XObjects are not dictionaries + dup type /dicttype eq { + dup /Subtype get /Form eq { + exch + 4 index 3 1 roll pdf_object_detect_cspacesub { + pop //true exit + } if + } { + pop pop + }ifelse + }{ pop pop - }ifelse + } ifelse }{ pop pop - } ifelse + } + ifelse }{ pop pop - } - ifelse - }{ - pop pop - } ifelse - } forall - }{ - pop + } ifelse + } forall + }{ + pop + }ifelse + } { + %% No forms, so can't be any Default* spaces + //false }ifelse } { - %% No forms, so can't be any Default* spaces //false - }ifelse - } { - //false + } ifelse } ifelse - } ifelse - %% Remove the calling object ID, return our boolean + %% Remove the calling object ID, return our boolean + exch pop exit + } loop + %% remove and discard the loopdict exch pop } bind def @@ -2966,12 +3195,11 @@ currentdict /PDF2PS_matrix_key undef % not using UseCIEColor with pdfwrite. % /pdfshowpage_detect_cspacesub { - dup 0 pdf_object_detect_cspacesub + dup 0 1 dict 3 1 roll pdf_object_detect_cspacesub /HighLevelDevice /GetDeviceParam .special_op { exch pop not exch pop }if - } bind def % @@ -3110,3 +3338,36 @@ currentdict /PDF2PS_matrix_key undef end % pdfdict .setglobal + +DELAYBIND not { +%% This list of operators are used internally by various parts of the Ghostscript PDF interpreter. +%% 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. +[ +/.pdfawidthshow /.pdfwidthshow +/.setfillcolor /.setfillcolorspace /.setstrokecolor /.setstrokecolorspace /.currentrenderingintent /.setrenderingintent +/.currenttextrenderingmode /.settextspacing /.currenttextspacing /.settextleading /.currenttextleading +/.settextrise /.currenttextrise /.setwordspacing /.currentwordspacing /.settexthscaling /.currenttexthscaling +/.settextlinematrix /.currenttextlinematrix /.currenttextmatrix /.settextmatrix /.currentblendmode +/.currentopacityalpha /.currentshapealpha /.currenttextknockout +/.pushextendedgstate /.popextendedgstate /.begintransparencytextgroup +/.endtransparencytextgroup /.begintransparencymaskgroup /.begintransparencymaskimage /.endtransparencymask /.image3x +/.abortpdf14devicefilter /.pdfinkpath /.pdfFormName /.setstrokeconstantalpha +/.setfillconstantalpha /.setalphaisshape /.currentalphaisshape +/.settextspacing /.currenttextspacing /.settextleading /.currenttextleading /.settextrise /.currenttextrise +/.setwordspacing /.currentwordspacing /.settexthscaling /.currenttexthscaling + +% Used by our own test suite files +%/.pushpdf14devicefilter % transparency-example.ps +%/.poppdf14devicefilter % transparency-example.ps +%/.setopacityalpha % transparency-example.ps +%/.setshapealpha % transparency-example.ps +%/.endtransparencygroup % transparency-example.ps + +% undefining these causes errors/incorrect output +%/.settextrenderingmode /.setblendmode /.begintransparencygroup /.settextknockout /check_r6_password /.setstrokeoverprint /.setfilloverprint +%/.currentstrokeoverprint /.currentfilloverprint /.currentfillconstantalpha /.currentstrokeconstantalpha +] +{systemdict exch .undef} forall +} if diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps index ba53b54cd7e..fabef68a90a 100644 --- a/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps +++ b/Master/tlpkg/tlgs/Resource/Init/pdf_ops.ps @@ -211,76 +211,69 @@ currentdict /gput_always_allow .undef } ifelse } bdef -% Save most of graphic state attributes. -% - get-gs-attrs ... -/get-gs-attrs { - currentsmoothness - currentflat - currentoverprint - currentstrokeadjust - currentdash - currentmiterlimit - currentlinejoin - currentlinecap - currentlinewidth - currentfont - currentcolor - currentcolorspace - { currentpoint } stopped - matrix currentmatrix -} bdef - -% Restore most of graphic state attributes. -% ... get-gs-attrs - -/set-gs-attrs { - setmatrix - { newpath } { moveto } ifelse - setcolorspace - setcolor - setfont - setlinewidth - setlinecap - setlinejoin - setmiterlimit - setdash - setstrokeadjust - setoverprint - setflat - setsmoothness -} bdef - % ---------------- Color setting ---------------- % -/fcput % fcput - - { /FillColorSpace gput /FillColor gput - } bdef -/scput % scput - - { /StrokeColorSpace gput /StrokeColor gput - } bdef -/csput % csput - - { csset 2 copy fcput scput - } bdef - -/csdevgray [/DeviceGray] readonly def -/csdevrgb [/DeviceRGB] readonly def -/csdevcmyk [/DeviceCMYK] readonly def -/cspattern [/Pattern] readonly def /nullpatternproc { pop } bdef /nullpattern mark /PatternType 1 /PaintType 1 /TilingType 3 /BBox [0 0 1 1] /XStep 1 /YStep 1 /PaintProc //nullpatternproc .dicttomark readonly def -% Each entry in the color space dictionary is a procedure of the form -% -proc- +/PDFsetpattern { + % Since multiple patterns may share + % same data stream, we need to ensure + % that the stream is at 0 position. + % Making this consistently with resolveshading, + % which applies ReusableStreamDecode filter + % to the PS stream, which represents the + % PDF stream in dynamics. + + dup /Shading knownoget { + dup /ShadingType oget 4 ge { + /DataSource knownoget { + dup type /filetype eq { + 0 setfileposition + } { + pop + } ifelse + } if + } { + pop + } ifelse + } if + + % Associate pattern instance with the default qstate for the context. + % A single pattren object can be reused in several contexts. + dup DefaultQstate .knownget { + exch pop + } { + % But don't update read-only initial null pattern. + dup /PaintProc .knownget { //nullpatternproc ne } { //true } ifelse { + dup dup /Matrix knownoget not { { 1 0 0 1 0 0 } } if + + gsave + .currentfillconstantalpha + .currentstrokeconstantalpha + DefaultQstate setqstate + .setstrokeconstantalpha + .setfillconstantalpha + makepattern + grestore + + dup 3 1 roll + DefaultQstate exch put + } if + } ifelse +} bdef + /CSdict mark - /DeviceGray { pop //csdevgray 0 } bind - /DeviceRGB { pop //csdevrgb [0 0 0] cvx } bind - /DeviceCMYK { pop //csdevcmyk [0 0 0 1] cvx } bind + /DeviceGray { 0 } bind + /DeviceRGB { [0 0 0] cvx } bind + /DeviceCMYK { [0 0 0 1] cvx } bind /CIEBasedA { 0 } bind /CIEBasedABC { [0 0 0] cvx } bind - /CalGray { pop //csdevgray 0 } bind - /CalRGB { pop //csdevrgb [0 0 0] cvx } bind + /CalGray { pop /DeviceGray 0 } bind + /CalRGB { pop /DeviceRGB [0 0 0] cvx } bind /Lab {[0 0 0] cvx } bind /ICCBased { [ 1 index 1 oget /N get { 0 } repeat ] cvx } bind /Separation { 1 } bind @@ -288,91 +281,111 @@ currentdict /gput_always_allow .undef [ 1 index 1 get length { 1 } repeat ] cvx } bind /Indexed { 0 } bind - /Pattern { - dup type /nametype eq 1 index length 1 eq or { - pop //cspattern //nullpattern matrix makepattern - } { - //nullpattern matrix makepattern 1 index 1 get csset - % Stack: patternspace nullpattern basecolor basespace - pop [ 3 1 roll dup type /arraytype eq { aload pop } if - counttomark -1 roll ] cvx - } ifelse - } bind + /Pattern { //nullpattern matrix makepattern } bind .dicttomark readonly def -/csset % csset - { dup dup type /nametype ne { 0 get } if //CSdict exch get exec exch - } bdef -/g { //csdevgray fcput } bdef -/G { //csdevgray scput } bdef -/rg { 3 array astore cvx //csdevrgb fcput } bdef -/RG { 3 array astore cvx //csdevrgb scput } bdef -/k { 4 array astore cvx //csdevcmyk fcput } bdef -/K { 4 array astore cvx //csdevcmyk scput } bdef -%% -%% Bug #694412, we set the colour space immediately now. Previously we -%% only set the colour space and colour when a stroke or fill took place. -%% if that happened inside a gsave/grestore we could end up setting the -%% same colour space many times, which is a problem if its an expensive -%% space, like ICCBased. -%% -/cs { csset dup setgcolorspace fcput } bdef -/CS { csset dup .swapcolors setgcolorspace .swapcolors scput } bdef -/ri { //.renderingintentdict exch .knownget { .setrenderingintent } if } bdef -% We have to break up sc according to the number of operands. -%% -%% Also Bug #694412, we need to set the actual colour in response to the -%% PDF operators as well. However, the transparenmcy code also uses the -%% original calls (sc, SC, sc1, SC1, sc* and SC*) and so we create -%% a duplicate set which do the same as the originals, but se the current -%% colour as well. -%% -/sc1_and_set { /FillColor gput FillColor FillColorSpace setgcolor} bdef -/sc1 { /FillColor gput } bdef -/SC1_and_set {/StrokeColor gput .swapcolors StrokeColor StrokeColorSpace setgcolor .swapcolors } bdef -/SC1 { /StrokeColor gput } bdef -% We have to avoid storing into a color array associated with an outer -% gsave level, so we do a kind of "copy on write". -/sc* { - currentdict /FillColor .knownget { - astore pop - } { - /FillColor load - % FillColor may contain either a single value or an array. - dup type /arraytype eq { length }{ pop 1 } ifelse - array astore cvx /FillColor gput - } ifelse -} bdef -/SC* { - currentdict /StrokeColor .knownget { - astore pop - } { - /StrokeColor load - % StrokeColor may contain either a single value or an array. - dup type /arraytype eq { length }{ pop 1 } ifelse - array astore cvx /StrokeColor gput - } ifelse -} bdef +/ri {//.renderingintentdict exch .knownget { .setrenderingintent } if } bdef +/g {/DeviceGray .setfillcolorspace .setfillcolor } bdef +/G {/DeviceGray .setstrokecolorspace .setstrokecolor} bdef +/rg {/DeviceRGB .setfillcolorspace .setfillcolor} bdef +/RG {/DeviceRGB .setstrokecolorspace .setstrokecolor} bdef +/k {/DeviceCMYK .setfillcolorspace .setfillcolor} bdef +/K {/DeviceCMYK .setstrokecolorspace .setstrokecolor} bdef +/cs {dup dup type /nametype ne { 0 get } if //CSdict exch get exec exch .setfillcolorspace exec .setfillcolor} bdef +/CS {dup dup type /nametype ne { 0 get } if //CSdict exch get exec exch .setstrokecolorspace exec .setstrokecolor} bdef +/sc {.setfillcolor} bdef +/SC {.setstrokecolor} bdef +/sc* {.setfillcolor} bdef +/SC* {.setstrokecolor} bdef /sc*_and_set { - sc* - FillColor FillColorSpace setgcolor + dup type /dicttype eq + { + dup /Type known + { + dup /Type get /Pattern eq {PDFsetpattern} if + } + { + dup /PatternType known {PDFsetpattern} if + } ifelse + } if + .setfillcolor } bdef /SC*_and_set { - SC* - .swapcolors StrokeColor StrokeColorSpace setgcolor .swapcolors + dup type /dicttype eq + { + dup /Type known + { + dup /Type get /Pattern eq {PDFsetpattern} if + } + { + dup /PatternType known {PDFsetpattern} if + } ifelse + } if + .setstrokecolor +} bdef +/sc1 {.setfillcolor} bdef +/SC1 {.setstrokecolor} bdef +/sc1_and_set { + dup type /dicttype eq + { + dup /Type known + { + dup /Type get /Pattern eq {PDFsetpattern} if + } + { + dup /PatternType known {PDFsetpattern} if + } ifelse + } if + .setfillcolor +} bdef +/SC1_and_set { + dup type /dicttype eq + { + dup /Type known + { + dup /Type get /Pattern eq {PDFsetpattern} if + } + { + dup /PatternType known {PDFsetpattern} if + } ifelse + } if + .setstrokecolor } bdef +/csput {dup dup type /nametype ne { 0 get } if //CSdict exch get exec exch 2 copy .setfillcolorspace exec .setfillcolor .setstrokecolorspace exec .setstrokecolor} bdef +/csset {dup dup type /nametype ne { 0 get } if //CSdict exch get exec exch} bdef + +% ---------------- Color setting ---------------- % + % ---------------- Overprint/transparency setting ---------------- % -/op { /FillOverprint gput } bdef % NB pdf_draw:gsparamdict handled /OP with no /op -/OP { /StrokeOverprint gput } bdef +/op { .setfilloverprint +} bdef % NB pdf_draw:gsparamdict handled /OP with no /op +/OP { .setstrokeoverprint +} bdef /OPM { /.setoverprintmode where { pop dup .setoverprintmode .swapcolors .setoverprintmode .swapcolors } { pop } ifelse } bdef -/ca { /FillConstantAlpha gput } bdef -/CA { /StrokeConstantAlpha gput } bdef -/SMask { /SoftMask gput } bdef -/AIS { /AlphaIsShape gput } bdef +/ca { .setfillconstantalpha } bdef +/CA { .setstrokeconstantalpha } bdef +/SMask { + dup type /booleantype eq { + .currentSMask type /dicttype eq { + .currentSMask /Processed 2 index .forceput + } { + .setSMask + }ifelse + }{ + .setSMask + }ifelse + + %% This is some craziness to do with annotations and graphics states + %% the original nodict can't be written to, and we haven't (I think) done + %% a gsave, so we haven't copied it to /self, if we don't do that here + %% then transparent annotations cause an invalid access error. + currentdict //nodict eq {/self dup load end 5 dict begin def} if +} bdef +/AIS { .setalphaisshape } bdef /BM { /.setblendmode where { pop [ exch dup type /nametype ne { aload pop } if /Normal ] { @@ -386,13 +399,19 @@ currentdict /gput_always_allow .undef /.settextknockout where { pop .settextknockout } { pop } ifelse } bdef +/UseBlackPtComp { + %% Our implementation of black point compensation uses 0 or 1, not a boolean + /.setblackptcomp where {pop false eq {0}{1}ifelse .setblackptcomp }{ pop } ifelse +} bdef + % ---------------- Color installation ---------------- % % Establish a given color (and color space) as current. /.settransparencyparams { % .settransparencyparams - PDFusingtransparency { /.begintransparencygroup where { - pop AlphaIsShape { + pop .currentalphaisshape + { 1 .setopacityalpha exch .setshapealpha 1 } { 1 .setshapealpha exch .setopacityalpha 0 @@ -415,23 +434,28 @@ currentdict /gput_always_allow .undef dup /Draw get exec } ifelse } { - dup /Draw get exec + dup /Processed .knownget { + { + pop pop + } { + dup /Draw get exec + }ifelse + }{ + dup /Draw get exec + } ifelse } ifelse } bdef % (Non-mask) images must execute setfillblend. /setfillblend { - FillOverprint setoverprint - FillConstantAlpha SoftMask .settransparencyparams + .currentfillconstantalpha + .currentSMask .settransparencyparams } def /setfillstate { - FillColor FillColorSpace setgcolor setfillblend + setfillblend } def - /setstrokestate { - .swapcolors - StrokeColor StrokeColorSpace setgcolor StrokeOverprint setoverprint - StrokeConstantAlpha SoftMask .settransparencyparams - .swapcolors + .currentstrokeconstantalpha + .currentSMask .settransparencyparams } def /Cdict 15 dict dup begin % -proc- - /DeviceGray { pop setgray } bdef @@ -530,7 +554,16 @@ currentdict /gput_always_allow .undef % But don't update read-only initial null pattern. dup /PaintProc .knownget { //nullpatternproc ne } { //true } ifelse { dup dup /Matrix knownoget not { { 1 0 0 1 0 0 } } if - gsave DefaultQstate setqstate makepattern grestore + + gsave + .currentfillconstantalpha + .currentstrokeconstantalpha + DefaultQstate setqstate + .setstrokeconstantalpha + .setfillconstantalpha + makepattern + grestore + dup 3 1 roll DefaultQstate exch put } if @@ -582,8 +615,10 @@ end def pop currentcolorspace 1 get % use the base space } if known { - /stroke ne { FillOverprint } { StrokeOverprint } ifelse - .currentblendmode dup /Normal eq exch /Compatible eq or not and + /stroke ne { .currentfilloverprint + } { .currentstrokeoverprint + } ifelse + .currentblendmode dup /Normal eq exch /Compatible eq or not and } { pop //false } ifelse @@ -592,23 +627,25 @@ end def /fsexec % fsexec - { PDFusingtransparency { - SoftMask //null ne { + .currentSMask //null ne { mark /Subtype /Group /Isolated //true .dicttomark pathbbox .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 - exch .currentblendmode exch .currentopacityalpha exch 4 -1 roll % save current values + .currentblendmode .currentopacityalpha 4 -2 roll % save current values /CompatibleOverprint .setblendmode 1 .setopacityalpha } if cvx exec { .endtransparencygroup .setopacityalpha .setblendmode % end the CompatibleOverprint group } if - SoftMask //null ne { - .endtransparencygroup + .currentSMask //null ne { + .endtransparencygroup .setopacityalpha .setshapealpha } if } { cvx exec @@ -792,29 +829,72 @@ end def % Clipping: -/Wdict 4 dict dup begin +/Wdict 8 dict dup begin /S { OFFlevels length 0 eq { gsave setstrokestate .swapcolors stroke .swapcolors grestore } if n } bdef /f { OFFlevels length 0 eq { gsave setfillstate fill grestore } if n } bdef /f* { OFFlevels length 0 eq { gsave setfillstate eofill grestore } if n } bdef +/B { + OFFlevels length 0 eq { + PDFusingtransparency { + % knockout trans group around the filled and stroked object + mark + /Isolated //true /Knockout //true + .dicttomark + % strokepath will return empty path (no currentpoint) if nothing is stroked + gsave {strokepath pathbbox } stopped grestore not + { + 1 .setopacityalpha + .begintransparencygroup + gsave setfillstate fill grestore + setstrokestate .swapcolors /stroke fsexec .swapcolors + .endtransparencygroup + } { + newpath pop + } ifelse + } { + gsave setfillstate fill grestore + setstrokestate .swapcolors /stroke fsexec .swapcolors + } ifelse + } if + n +} bdef +/b { closepath B } bdef +/B* { + OFFlevels length 0 eq { + PDFusingtransparency { + % knockout trans group around the filled and stroked object + mark + /Isolated //true /Knockout //true + .dicttomark + % strokepath will return empty path (no currentpoint) if nothing is stroked + gsave {strokepath pathbbox} stopped grestore not { + 1 .setopacityalpha + .begintransparencygroup + gsave setfillstate eofill grestore + setstrokestate .swapcolors /stroke fsexec .swapcolors + .endtransparencygroup + } { newpath pop } ifelse + } { + gsave setfillstate eofill grestore + setstrokestate .swapcolors /stroke fsexec .swapcolors + } ifelse + } if + n +} bdef +/b { closepath B* } bdef /n { end { currentpoint } stopped not { pop pop clip } if newpath } bdef end readonly def /W { //Wdict begin } bdef -/W*dict 4 dict dup begin +/W*dict 8 dict dup begin Wdict { def } forall /n { end { currentpoint } stopped not { pop pop eoclip } if newpath } bdef end readonly def /W* { //W*dict begin } bdef - % ---------------- Text control ---------------- % /textbeginpage - { /TextSpacing 0 def % 0 Tc - /TextLeading 0 def % 0 TL - /TextRenderingMode 0 def % 0 Tr - /TextRise 0 def % 0 Ts - /WordSpacing 0 def % 0 Tw - /TextHScaling 1.0 def % 100 Tz - /TextFont //null def + { + 1.0 .settexthscaling /FontMatrixNonHV //false def /Show { showfirst } def /TextFillStateNeeded //true def @@ -844,7 +924,8 @@ end readonly def /settextmatrix { matrix currentmatrix - TextMatrix concat + matrix .currenttextmatrix + concat TestDegenerateCTM { (\n **** Error: Degenerate text matrix detected, ignoring Tm operation\n) pdfformaterror ( Output may be incorrect.\n) pdfformaterror @@ -852,9 +933,11 @@ end readonly def } { pop } ifelse - TextHScaling 1 ne { TextHScaling 1 scale } if - TextRise 0 ne { 0 TextRise translate } if - TextFont dup //null eq { pop } { setfont } ifelse + .currenttexthscaling + 1 ne { .currenttexthscaling + 1 scale } if + .currenttextrise 0 ne { 0 .currenttextrise + translate } if } bdef /settextstate { @@ -879,14 +962,22 @@ end readonly def /settextposition { % Update the TextMatrix translation. gsave TextSaveMatrix setmatrix - {currentpoint} stopped not { TextRise sub TextMatrix 4 2 getinterval astore pop + {currentpoint} stopped not { + .currenttextrise + sub + matrix .currenttextmatrix + dup 5 4 -1 roll put + dup 4 4 -1 roll put + .settextmatrix % We would like to do "grestore currentpoint translate" % here, but some PDF files set a singular text matrix % (0 0 0 0 Tm), so we can't do this. - TextTempMatrix identmatrix setmatrix currentpoint - grestore - TextTempMatrix currentmatrix 4 2 getinterval astore pop - TextTempMatrix setmatrix + TextTempMatrix identmatrix setmatrix currentpoint + matrix .currenttextmatrix + grestore + .settextmatrix + TextTempMatrix currentmatrix 4 2 getinterval astore pop + TextTempMatrix setmatrix } { ( **** Error: Invalid currentpoint, probable degenerate CTM.\n) pdfformaterror ( Ignroing error, output may be incorrect.\n) pdfformaterror @@ -932,10 +1023,9 @@ end readonly def currentdict end /.W exch def } if - currentdict /TextLineMatrix .knownget - { identmatrix pop TextMatrix identmatrix pop } - { matrix /TextLineMatrix gput matrix /TextMatrix gput } - ifelse + matrix .settextlinematrix + matrix .settextmatrix + { showfirst } /Show gput currentdict /TextSaveMatrix .knownget not { matrix dup /TextSaveMatrix gput @@ -957,7 +1047,7 @@ end readonly def /ET_NO_TXT_KO { currentdict /TextSaveMatrix known { - TextRenderingMode 4 ge { .currentfilladjust 0 .setfilladjust clip .setfilladjust} if + .currenttextrenderingmode 4 ge { .currentfilladjust 0 .setfilladjust clip .setfilladjust} if newpath TextSaveMatrix setmatrix currentdict /TextSaveMatrix undef @@ -988,11 +1078,11 @@ end readonly def } if } bdef -/Tc { /TextSpacing gput { showfirst } /Show gput } bdef -/TL { /TextLeading gput } bdef -/Tr { dup .settextrenderingmode /TextRenderingMode gput { showfirst } /Show gput } bdef -/Ts { /TextRise gput settextstate } bdef -/Tw { /WordSpacing gput { showfirst } /Show gput } bdef +/Tc { .settextspacing { showfirst } /Show gput } bdef +/TL { .settextleading } bdef +/Tr { .settextrenderingmode { showfirst } /Show gput } bdef +/Ts { .settextrise settextstate } bdef +/Tw { .setwordspacing { showfirst } /Show gput } bdef /Tz { dup 0 eq { (\n **** Error: Invalid 0.0 horizontal text scaling given for Tz\n) @@ -1001,7 +1091,8 @@ end readonly def pop 0.00000001 % handle invalid scale by using a really small value }{ 100 div - }ifelse /TextHScaling gput settextstate} bdef + }ifelse .settexthscaling %/TextHScaling gput + settextstate} bdef % ---------------- Font control ---------------- % @@ -1080,7 +1171,7 @@ end readonly def } { pop } ifelse - /TextFont gput settextstate + setfont } bdef % Copy a font, removing its FID. If changed is true, also remove @@ -1210,11 +1301,17 @@ end readonly def ( Output may be incorrect.\n) pdfformaterror pop 0 } if - TextLineMatrix transform TextLineMatrix 4 2 getinterval astore pop - TextLineMatrix TextMatrix copy pop settextstate + matrix .currenttextlinematrix transform + matrix .currenttextlinematrix + dup 3 -1 roll 5 exch put + dup 3 -1 roll 4 exch put + .settextlinematrix + matrix .currenttextlinematrix .settextmatrix + + settextstate } bdef -/TD { dup neg /TextLeading gput Td } bdef -/T* { 0 TextLeading neg Td } bdef +/TD { dup neg .settextleading Td } bdef +/T* { 0 .currenttextleading neg Td } bdef /Tm { 5 index 0 ne 3 index 0 ne and 5 index 0 ne 5 index 0 ne and or not { @@ -1226,7 +1323,9 @@ end readonly def 0.00000001 0 0 0.00000001 6 -2 roll }if - TextLineMatrix astore TextMatrix copy pop settextstate + matrix .currenttextlinematrix astore .settextlinematrix + matrix .currenttextlinematrix .settextmatrix + settextstate } bdef % ---------------- Text painting ---------------- % @@ -1329,8 +1428,8 @@ end readonly def //false }ifelse { - TextRenderingMode 1 eq TextRenderingMode 2 eq or - TextRenderingMode 5 eq TextRenderingMode 6 eq or or { + .currenttextrenderingmode 1 eq .currenttextrenderingmode 2 eq or + .currenttextrenderingmode 5 eq .currenttextrenderingmode 6 eq or or { setstrokestate % Need to set the stroke width to a value which gives the correct % width under pdfwrite. Pdfwrite uses (in text mode) an identity @@ -1360,7 +1459,7 @@ end readonly def /TextTransSetup { % showarg path_valid TextTransSetup false showarg % showarg path_valid false TextTransSetup prev_BM prev_opacity true showarg % NB: if 'show' is used, then we use the clippath, but a smaller bbox is preferred - SoftMask //null ne { + .currentSMask //null ne { dup mark /Subtype /Group /Isolated //true .dicttomark exch { pathbbox } { gsave clippath pathbbox grestore } ifelse .begintransparencygroup @@ -1385,13 +1484,15 @@ end readonly def .endtransparencygroup OPsavedict dup /saveOA get .setopacityalpha /saveBM get .setblendmode } if - SoftMask //null ne { + .currentSMask //null ne { .endtransparencygroup } if } bind def /setshowstate - { WordSpacing 0 eq TextSpacing 0 eq and FontMatrixNonHV not and + { + .currentwordspacing 0 eq .currenttextspacing + 0 eq and FontMatrixNonHV not and { % Check to see if the current device supports Tr /PreserveTrMode /GetDeviceParam .special_op { @@ -1400,16 +1501,16 @@ end readonly def //false }ifelse { - pdfwrite_textrenderingprocs TextRenderingMode get + pdfwrite_textrenderingprocs .currenttextrenderingmode get } { - TextRenderingMode 0 eq - currentfont /FontType get 3 eq TextRenderingMode 3 eq not + .currenttextrenderingmode 0 eq + currentfont /FontType get 3 eq .currenttextrenderingmode 3 eq not and or { { settextfillstate //false TextTransSetup show TextTransTeardown } } { - TextRenderingMode 3 eq { + .currenttextrenderingmode 3 eq { % Some PDF files execute 'tm' with a singular matrix, % and then use the text rendering mode 3. % The graphics library currently cannot handle text @@ -1437,7 +1538,7 @@ end readonly def moveto } } { - { //false charpath textrenderingprocs TextRenderingMode get exec } + { //false charpath textrenderingprocs .currenttextrenderingmode get exec } } ifelse } ifelse } ifelse @@ -1446,7 +1547,7 @@ end readonly def % If we are doing a plain old fill, or no text at all, *or* we are going to % a device supporting text rendering modes, then go through this route. % - TextRenderingMode 0 eq TextRenderingMode 3 eq or + .currenttextrenderingmode 0 eq .currenttextrenderingmode 3 eq or currentfont /FontType get 3 eq or /PreserveTrMode /GetDeviceParam .special_op { @@ -1455,7 +1556,7 @@ end readonly def //false }ifelse % pdfwrite can't handle rendering modes which involve clipping - TextRenderingMode 4 lt and or + .currenttextrenderingmode 4 lt and or % Tr was set to graphic state. { FontMatrixNonHV { @@ -1464,7 +1565,7 @@ end readonly def currentlinewidth exch setstrokeforTrpreservation settextfillstate //false TextTransSetup - [ TextSpacing WordSpacing 3 index + [ .currenttextspacing .currentwordspacing 3 index { % str [... weach wword c undef|ythis xthis|undef exch % will be removed, unless FontMatrix.xx/yy == 0 (FontMatrixNonHV already true) Vexch pop % str [... weach wword c wthis @@ -1480,20 +1581,23 @@ end readonly def setlinewidth TextTransTeardown } } { - WordSpacing 0 eq { + .currentwordspacing + 0 eq { { { setstrokeforTrpreservation - settextfillstate //false TextTransSetup TextSpacing 0 Vexch 3 -1 roll ashow TextTransTeardown + settextfillstate //false TextTransSetup .currenttextspacing + 0 Vexch 3 -1 roll ashow TextTransTeardown } currentlinewidth { setlinewidth } 3 .execn } } { - TextSpacing 0 eq { + .currenttextspacing 0 eq { { % preserve current line width around possible stroke setup { setstrokeforTrpreservation - settextfillstate //false TextTransSetup WordSpacing 0 Vexch 32 4 -1 roll .pdfwidthshow + settextfillstate //false TextTransSetup .currentwordspacing + 0 Vexch 32 4 -1 roll .pdfwidthshow TextTransTeardown } currentlinewidth @@ -1503,8 +1607,9 @@ end readonly def } { { % preserve current line width around possible stroke setup { setstrokeforTrpreservation - settextfillstate //false TextTransSetup WordSpacing 0 Vexch 32 - TextSpacing 0 Vexch 6 -1 roll .pdfawidthshow TextTransTeardown + settextfillstate //false TextTransSetup .currentwordspacing + 0 Vexch 32 + .currenttextspacing 0 Vexch 6 -1 roll .pdfawidthshow TextTransTeardown } currentlinewidth { setlinewidth } @@ -1516,7 +1621,8 @@ end readonly def } { { currentlinewidth exch - WordSpacing TextSpacing + .currentwordspacing + .currenttextspacing % Implement the combination of t3 and false charpath. % Note that we must use cshow for this, because we % can't parse multi-byte strings any other way. @@ -1543,7 +1649,7 @@ end readonly def % or we wouldn't be here. Subtract 4 from the Tr and preserve % that mode, then do a charpath so the clip path gets set up % correctly. - gsave TextRenderingMode 4 sub .settextrenderingmode + gsave .currenttextrenderingmode 4 sub .settextrenderingmode setstrokeforTrpreservation setstrokestate settextfillstate //false TextTransSetup dup show grestore TextTransTeardown } if //false charpath @@ -1569,7 +1675,7 @@ end readonly def }{ //true }ifelse { - textrenderingprocs TextRenderingMode get exec + textrenderingprocs .currenttextrenderingmode get exec } if setlinewidth } @@ -1588,9 +1694,7 @@ end readonly def OFFlevels length 0 eq { exec } { - gsave get-gs-attrs nulldevice set-gs-attrs - exec - get-gs-attrs grestore set-gs-attrs + gsave nulldevice exec grestore } ifelse //true /TextFillStateNeeded gput } bdef @@ -1610,9 +1714,7 @@ end readonly def OFFlevels length 0 eq { exec } { - gsave get-gs-attrs nulldevice set-gs-attrs - exec - get-gs-attrs grestore set-gs-attrs + gsave nulldevice exec grestore } ifelse //true /TextFillStateNeeded gput } bdef @@ -1741,9 +1843,13 @@ end readonly def 2 0 moveto % start at bottom left of rect counttomark 1 1 3 -1 roll { % for every string pop gsave - anchorsearch { - pop - } if + anchorsearch { + pop + } { + anchorsearch { + pop + } if + } ifelse Show grestore % pop loop counter, show string (saving current point) counttomark 1 add index 0 exch rmoveto % get line height, move that amount vertically. } for @@ -1755,9 +1861,13 @@ end readonly def 2 0 moveto % start at bottom left of rect counttomark 1 1 3 -1 roll { % for every string pop gsave % pop loop counter - anchorsearch { - pop - } if + anchorsearch { + pop + } { + anchorsearch { + pop + } if + } ifelse dup stringwidth pop counttomark 5 add index % get rectangle width exch sub 2 div 0 rmoveto % subtract width of string, divide by 2 move that amount Show grestore % show string @@ -1770,9 +1880,13 @@ end readonly def 2 0 moveto % start at bottom left of rect counttomark 1 1 3 -1 roll { % for every string pop gsave % pop loop counter - anchorsearch { + anchorsearch { pop - } if + } { + anchorsearch { + pop + } if + } ifelse dup stringwidth pop counttomark 5 add index % get rectangle width exch sub 2 sub 0 rmoveto % subtract width of string,move that amount Show grestore % show string @@ -1790,9 +1904,13 @@ end readonly def 0 exch moveto % MaxLen (V) Ff Q dx 1 index 0 ne { 3 index - anchorsearch { - pop - } if + anchorsearch { + pop + } { + anchorsearch { + pop + } if + } ifelse stringwidth pop % MaxLen (V) Ff Q dx w sub exch 1 eq { 2 div } { 2 sub } ifelse % MaxLen (V) Ff (dx-w)/2 0 rmoveto % MaxLen (V) Ff @@ -1802,9 +1920,13 @@ end readonly def 2 0 rmoveto } ifelse exch pop - anchorsearch { + anchorsearch { pop - } if + } { + anchorsearch { + pop + } if + } ifelse Show % - } ifelse } ifelse -- cgit v1.2.3