diff options
Diffstat (limited to 'Master/xemtex/gslib/pdf_main.ps')
-rw-r--r-- | Master/xemtex/gslib/pdf_main.ps | 813 |
1 files changed, 813 insertions, 0 deletions
diff --git a/Master/xemtex/gslib/pdf_main.ps b/Master/xemtex/gslib/pdf_main.ps new file mode 100644 index 00000000000..fd87aa5c99d --- /dev/null +++ b/Master/xemtex/gslib/pdf_main.ps @@ -0,0 +1,813 @@ +% Copyright (C) 1994, 2000 Aladdin Enterprises. All rights reserved. +% +% This program is free software; you can redistribute it and/or modify it +% under the terms of the GNU General Public License as published by the +% Free Software Foundation; either version 2 of the License, or (at your +% option) any later version. +% +% This program is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +% Public License for more details. +% +% You should have received a copy of the GNU General Public License along +% with this program; if not, write to the Free Software Foundation, Inc., +% 59 Temple Place, Suite 330, Boston, MA, 02111-1307. + +% $Id: pdf_main.ps,v 1.35.2.7.2.3 2003/04/12 14:02:39 giles Exp $ +% pdf_main.ps +% PDF file- and page-level operations. + +/.setlanguagelevel where { pop 2 .setlanguagelevel } if +.currentglobal true .setglobal +/pdfdict where { pop } { /pdfdict 100 dict def } ifelse +pdfdict begin + +% Patch in an obsolete variable used by some third-party software. +/#? false def + +% Test whether the current output device handles pdfmark. +/.writepdfmarkdict 1 dict dup /pdfmark null put readonly def +/.writepdfmarks { % - .writepdfmarks <bool> + currentdevice //.writepdfmarkdict .getdeviceparams + mark eq { false } { pop pop true } ifelse + systemdict /DOPDFMARKS known or +} bind def + +% For simplicity, we use a single interpretation dictionary for all +% PDF graphics execution, even though this is too liberal. +/pdfopdict mark + objopdict { } forall + drawopdict { } forall + /endstream { exit } bind + (%%EOF) cvn { exit } bind % for filters + % PDF 1.1 operators + /BX { /BXlevel BXlevel 1 add store } bind + /EX { /BXlevel BXlevel 1 sub store } bind + /PS { cvx exec } bind + % PDF 1.2 operators + /BMC { pop } bind + /BDC { pop pop } bind + /EMC { } + /MP { pop } bind + /DP { pop pop } bind +.dicttomark readonly def + +% ======================== Main program ======================== % + +end % pdfdict +userdict begin + +/defaultfontname /Times-Roman def + +% Make sure the registered encodings are loaded, so we don't run the risk +% that some of the indices for their names will overflow the packed +% representation. (Yes, this is a hack.) +SymbolEncoding pop +DingbatsEncoding pop + +% Redefine 'run' so it recognizes PDF files. +systemdict begin +/.runps /run load def +/run { + dup type /filetype ne { (r) file } if + dup ( ) .peekstring { + (%) eq { + dup ( ) .peekstring { + (%PDF-) eq { + dup (%stdin) (r) file eq { + % Copy PDF from stdin to temporary file then run it. + null (w+) //systemdict /.tempfile get exec exch 3 1 roll + % stack: tempname stdin tempfile + 1024 string + { + % stack: tempname stdin tempfile string + 2 index 1 index readstring + exch 3 index exch writestring + not { exit } if + } + loop + pop exch closefile + % stack: tempname tempfile + dup 0 setfileposition + dup runpdf + closefile deletefile + } { + runpdf + } ifelse + } { + cvx .runps % doesn't start with %PDF- + } ifelse + } { + pop cvx .runps % didn't read 5 characters + } ifelse + } { + cvx .runps % didn't start with % + } ifelse + } { + pop closefile % file was empty + } ifelse +} bind odef +currentdict /runpdfstring .undef + +/runpdf { % <file> runpdf - + userdict begin + % It turns out that the PDF interpreter uses memory more + % effectively if it is run under at least one level of save. + % This is counter-intuitive, and we don't understand why it happens, + % but the improvement is significant. + /PDFTopSave save def + /Page# null def + /Page null def + /DSCPageCount 0 def + /PDFSave null def + GS_PDF_ProcSet begin + pdfdict begin + pdfopen begin + Trailer /Root oget /Pages oget /CropBox knownoget + { mark /CropBox 3 -1 roll /PAGES pdfmark + } + if + /FirstPage where + { pop FirstPage dup pdfpagecount gt + { (\nRequested FirstPage is greater than the number of pages in the file: ) print + pdfpagecount = flush + } if + } { + 1 + } ifelse + 1 + /LastPage where { pop LastPage pdfpagecount .min } { pdfpagecount } ifelse + 2 index 1 index gt + { ( No pages will be processed \(FirstPage > LastPage\).) = flush } + { QUIET not + { (Processing pages ) print 2 index =only ( through ) print dup =only + (.) = flush + } + if + } + ifelse + { dup /Page# exch store + QUIET not { (Page ) print dup == flush } if + pdfgetpage pdfshowpage + } for + currentdict pdfclose + end % temporary dict + end % pdfdict + end % userdict + end % GS_PDF_ProcSet + PDFTopSave restore +} bind def +end % systemdict +% Redefine the procedure that the C code uses for running piped input. +% It is OK to use { (%stdin) run } here, because a startjob cannot occur. +/.runstdin { + { (%stdin) run } execute0 +} bind def + +end % userdict +pdfdict begin + +% ======================== File parsing ======================== % + +% Read the cross-reference and trailer sections. + +/traileropdict mark + (<<) cvn { mark } bind + (>>) cvn /.dicttomark load + ([) cvn { mark } bind % ditto + (]) cvn dup load +% /true true % see .pdfexectoken in pdf_base.ps +% /false false % ibid. +% /null null % ibid. + /R { /resolveR cvx 3 packedarray cvx } bind % see Objects below + /startxref /exit load +.dicttomark readonly def + +% Because of EOL conversion, lines with fixed contents might be followed +% by one or more blanks. +/lineeq % <filestr> <conststr> lineeq <bool> + { anchorsearch + { pop { ( ) anchorsearch not { () eq exit } if pop } loop } + { pop false } + ifelse + } bind def +/linene { lineeq not } bind def + +% Read (mostly scan) the cross-reference table. +/readxref % <pos> readxref <trailerdict> + { PDFoffset add PDFfile exch setfileposition + % In some PDF files, this position actually points to + % white space before the xref line. Skip over this here. + { PDFfile fileposition PDFfile read pop 32 gt { exit } if pop + } loop + PDFfile exch setfileposition + % The PDF specification says that the 'xref' must be on a line + % by itself. The code here formerly used readline and linene to + % check this. However, Acrobat Reader only requires the line to + % begin with 'xref', and there are enough applications producing + % non-compliant PDF files that we have to do this too. + PDFfile pdfstring 0 4 getinterval readstring pop + (xref) ne { /readxref cvx /syntaxerror signalerror } if + % Store the xref table entry position for each object. + % We only need to read the run headers, not every entry. + { PDFfile token pop % first object # or trailer + dup /trailer eq { pop exit } if + PDFfile pdfstring readline pop + token pop % entry count + exch pop exch + % This section might be adding new objects: + % ensure that Objects and Generations are big enough. + % Stack: count obj# + 2 copy add growPDFobjects + PDFfile fileposition 3 -1 roll + { Objects 2 index lget null eq % later update might have set it + { Objects 2 index 2 index cvx lput } + if exch 1 add exch 20 add + } + repeat PDFfile exch setfileposition pop + } loop + count /pdfemptycount exch def + PDFfile traileropdict .pdfrun + } bind def + +% Open a PDF file and read the header, trailer, and cross-reference. +/pdfopen { % <file> pdfopen <dict> + pdfopenfile begin + pdfopencache + .writepdfmarks { + % Copy bookmarks (outline) to the output. + Trailer /Root oget /Outlines knownoget { + /First knownoget { + { dup writeoutline /Next knownoget not { exit } if } loop + } if + } if + } if % end .writepdfmarks + currentdict end +} bind def +/pdfopencache { % - pdfopencache - + % Create and initialize some caches. + /PageCount pdfpagecount def + /PageNumbers PageCount 65534 .min dict def + /PageIndex PageCount 65534 .min array def +} bind def +/pdfopenfile { % <file> pdfopenfile <dict> + pdfdict readonly pop % can't do it any earlier than this + 15 dict begin + /LocalResources 0 dict def + /DefaultMatrix null def % establish binding + /Printed where { pop } { + % Guess whether the output device is a printer. + /Printed currentpagedevice /OutputFile known def + } ifelse + /PSLevel1 where { pop } { /PSLevel1 false def } ifelse + cvlit /PDFfile exch def + /PDFsource PDFfile def + /Repaired false def + PDFfile dup 0 setfileposition pdfstring readstring + not {/pdfopen cvx /syntaxerror signalerror} if + (%PDF-) search not {/pdfopen cvx /syntaxerror signalerror} if + length /PDFoffset exch def pop cvr /PDFversion exch def + findxref + initPDFobjects + % Read the last cross-reference table. + readxref /Trailer exch def + Trailer /Encrypt known + { pdf_process_Encrypt % signal error + } + if + % Read any previous cross-reference tables. + Trailer { /Prev .knownget not { exit } if readxref } loop + Repaired { printrepaired } if + currentdict end + } bind def + +% Skip backward over the %%EOF at the end of the PDF file, and read +% the preceding startxref line. The PDF specification unambiguously +% requires that the %%EOF appear on a line by itself, and that the +% startxref and the following position value appear on separate lines; +% however, some applications (including, apparently, Acrobat Distiller +% on the Macintosh) may add up to 2K of garbage after the %%EOF, and some +% other applications also truncate the %%EOF to %%EO, and/or put the +% startxref and the following value on the same line. +% A file reported from Distiller 3.02b for AIX 4.1.1 has 2076 bytes +% of garbage. The tolerance is increased to 4K to cover future +% applications and bigger allocation units. +/findxref { % - findxref <xrefpos> + PDFfile dup dup 0 setfileposition bytesavailable + dup /PDFfilelen exch def + % Find the last %%EOF string (within 4096 bytes) + 4096 sub PDFoffset .max + 2 copy setfileposition + PDFfilelen exch sub string 1 index exch readstring pop { + (\015%%EO) search { % Adobe can handle truncated key string + pop pop % if found, keep searching 'post' string + } { + (\012%%EO) search + { pop pop } { exit } ifelse % exit if neither string found + } ifelse + } loop + PDFfilelen exch length sub 4 sub PDFoffset .max exch 1 index setfileposition + % Stack: eofpos + % Check for whether this is, in fact, a valid PDF file. + dup PDFfilelen exch sub dup dup 7 gt exch 6 lt or { + pop true + } { + string PDFfile exch readstring pop + dup (%%EOF\n) eq exch dup (%%EOF\r) eq + exch (%%EOF\r\n) eq or or not + } ifelse { + ( + **** This file has a corrupted %%EOF marker, or garbage after the %%EOF. +) pdfformaterror + } if + PDFfile exch setfileposition + % Now read the startxref and xref start position. + prevline token not { null } if dup type /integertype eq { + exch pop cvi % xref start position + exch PDFfile exch setfileposition + prevline (startxref) linene { /findxref cvx /syntaxerror signalerror } if + pop + } { % else, this file has 'startxref #####' format + (startxref) ne { /findxref cvx /syntaxerror signalerror } if + cvi % xref start position + ( + **** The format of the startxref line in this file is invalid. +) pdfformaterror + exch PDFfile exch setfileposition + } ifelse +} bind def +/stderrfile (%stderr) (w) file def +/stderrprint { % <string> stderrprint - + //stderrfile dup 3 -1 roll writestring flushfile +} bind def +/pdfformaterror { % <string> pdfformaterror - + stderrprint + /Repaired true store +} bind def +/printrepaired { + Trailer /Info knownoget { + /Producer knownoget not { null } if + } { + null + } ifelse + dup null eq { + pop (\ + **** Please notify the author of the software that produced this file +) + } { + ( **** The file was produced by ) stderrprint + % Handle a Unicode Producer. + (\376\377) anchorsearch { + pop dup length 2 idiv string 0 1 2 index length 1 sub { + % Stack: origstr newstr i + 1 index exch 3 index 1 index 2 mul 1 add get put + } for exch pop + } if + stderrprint + (: + **** please notify the author of this software +) + } ifelse stderrprint +(\ + **** that the file does not conform to Adobe's published PDF + **** specification. Processing of the file will continue normally. + +) stderrprint +} bind def + +% Write the outline structure for a file. Uses linkdest (below). +/writeoutline % <outlinedict> writeoutline - + { mark + 0 2 index /First knownoget + { { exch 1 add exch /Next knownoget not { exit } if } loop } + if + % stack: dict mark count + dup 0 eq + { pop 1 index + } + { 2 index /Count knownoget { 0 lt { neg } if } if + /Count exch 3 index + } + ifelse linkdest /Title oget /Title exch /OUT pdfmark + /First knownoget + { { dup writeoutline /Next knownoget not { exit } if } loop } + if + } bind def + +% Close a PDF file. +/pdfclose % <dict> pdfclose - + { begin + PDFfile closefile + end + } bind def + +% ======================== Page accessing ======================== % + +% Get a (possibly inherited) attribute of a page. +/pget % <pagedict> <key> pget <value> -true- + % <pagedict> <key> pget -false- + { 2 copy knownoget + { exch pop exch pop true + } + { exch /Parent knownoget + { exch pget } + { pop false } + ifelse + } + ifelse + } bind def + +% Get the value of a resource on a given page. +/rget { % <resname> <pagedict> <restype> rget <value> -true- + % <resname> <pagedict> <restype> rget -false- + LocalResources 1 index knownoget { + 3 index knownoget + } { + false + } ifelse { + exch pop exch pop exch pop true + } { + exch /Resources pget { + exch knownoget { exch knownoget } { pop false } ifelse + } { + pop pop false + } ifelse + } ifelse +} bind def + +% Get the total number of pages in the document. +/pdfpagecount % - pdfpagecount <int> + { Trailer /Root oget /Pages oget /Count oget + } bind def + +% Find the N'th page of the document by iterating through the Pages tree. +% The first page is numbered 1. +/pdffindpageref { % <int> pdffindpage <objref> + dup Trailer /Root oget /Pages get + { % We should be able to tell when we reach a leaf + % by finding a Type unequal to /Pages. Unfortunately, + % some files distributed by Adobe lack the Type key + % in some of the Pages nodes! Instead, we check for Kids. + dup oforce /Kids knownoget not { exit } if + exch pop null + 0 1 3 index length 1 sub { + 2 index exch get + dup oforce dup /Kids known { /Count oget } { pop 1 } ifelse + % Stack: index kids null noderef count + dup 5 index ge { pop exch pop exit } if + 5 -1 roll exch sub 4 1 roll pop + } for exch pop + % Stack: index null|noderef + dup null eq { pop pop 1 null exit } if + } loop + % Stack: index countleft noderef + 1 index 1 ne { pop pop /pdffindpage cvx /rangecheck signalerror } if + exch pop + PageIndex 2 index 1 sub 65533 .min 2 index oforce put + PageNumbers 1 index oforce 3 index dup 65534 le + { put } + { pop pop pop } % don't store more than 65534 pagenumbers + ifelse + exch pop +} bind def +/pdffindpage { % <int> pdffindpage <pagedict> + pdffindpageref oforce +} bind def + +% Find the N'th page of the document. +% The first page is numbered 1. +/pdfgetpage % <int> pdfgetpage <pagedict> + { PageIndex 1 index 1 sub dup 65533 lt + { get } + { pop pop null } + ifelse + dup null ne + { exch pop oforce } + { pop pdffindpage } + ifelse + } bind def + +% Find the page number of a page object (inverse of pdfgetpage). +/pdfpagenumber % <pagedict> pdfpagenumber <int> + { % We use the simplest and stupidest of all possible algorithms.... + PageNumbers 1 index .knownget + { exch pop + } + { 1 1 PageCount 1 add % will give a rangecheck if not found + { dup pdfgetpage oforce 2 index eq { exit } if pop + } + for exch pop + } + ifelse + } bind def + +% Display a given page. +/boxrect % [<llx> <lly> <urx> <ury>] boxrect <x> <y> <w> <h> + { aload pop exch 3 index sub exch 2 index sub + } bind def +/resolvedest { % <name|string|other> resolvedest <other|null> + dup type /nametype eq { + Trailer /Root oget /Dests knownoget { + exch knownoget not { null } if + } { + null + } ifelse + } { + dup type /stringtype eq { + Trailer /Root oget /Names knownoget { + /Dests knownoget { + exch nameoget + } { + pop null + } ifelse + } { + pop null + } ifelse + } if + } ifelse +} bind def +/linkdest { % <link|outline> linkdest + % ([/Page <n>] /View <view> | ) <link|outline> + dup /Dest knownoget + { resolvedest + dup type /dicttype eq { /D knownoget not { null } if } if + dup null eq + { pop } + { dup 0 oget + dup null eq + { pop } + { dup type /integertype ne { pdfpagenumber } if + /Page exch 4 -2 roll + } + ifelse + dup length 1 sub 1 exch getinterval /View exch 3 -1 roll + } + ifelse + } + if +} bind def +% <pagedict> mark ... -proc- - +/namedactions 8 dict dup begin + /FirstPage { + /Page 1 3 -1 roll + } def + /LastPage { + counttomark 2 add index pdfpagecount /Page exch 3 -1 roll + } def + /NextPage { + counttomark 2 add index pdfpagenumber 1 add /Page exch 3 -1 roll + } def + /PrevPage { + counttomark 2 add index pdfpagenumber 1 sub /Page exch 3 -1 roll + } def +end readonly def +% <pagedict> <annotdict> -proc- - +/annottypes 5 dict dup begin + /Text { + mark exch + { /Rect /Open /Contents } + { 2 copy knownoget { 3 -1 roll } { pop } ifelse } + forall pop /ANN pdfmark + } bind def + /Link { + mark exch + dup /C knownoget { /Color exch 3 -1 roll } if + { /Rect /Border } + { 2 copy knownoget { 3 -1 roll } { pop } ifelse } + forall dup /A knownoget { + dup /URI known { + /A mark 3 2 roll % <<>> /A [ <<action>> + { oforce } forall + .dicttomark + 3 2 roll + } { + dup /D knownoget { + exch pop exch dup length dict copy dup /Dest 4 -1 roll put + } { + /N knownoget { % Assume /S /Named + namedactions exch .knownget { exec } if + } if + } ifelse + } ifelse + } if + linkdest pop /LNK pdfmark + } bind def +end readonly def + +/pdfshowpage % <pagedict> pdfshowpage - + { dup /Page exch store + pdfshowpage_init + pdfshowpage_setpage + pdfshowpage_finish + } bind def + +/pdfpagecontents % <pagedict> pdfpagecontents <contents> + { } bind def + +/pdfshowpage_init % <pagedict> pdfshowpage_init <pagedict> + { /DSCPageCount DSCPageCount 1 add store + } bind def + +/.pdfshowpage_Install { % <pagedict> [<prevproc>] .pdfshowpage_Install - + exch + % We would like to clip to the CropBox here, but the subsequent + % initgraphics would override it. Instead, we have to handle it + % in graphicsbeginpage. + dup /CropBox pget dup {exch pop} if systemdict /UseCropBox known and { + dup /CropBox pget pop dup 0 get neg exch 1 get neg translate + } { + dup /MediaBox pget { + dup 0 get neg exch 1 get neg translate + } if + } ifelse + pop 0 get exec +} bind def + +/pdfshowpage_setpage { % <pagedict> pdfshowpage_setpage <pagedict> + 4 dict begin % for setpagedevice + % Stack: pagedict + currentpagedevice /Orientation 2 index /Rotate pget not { 0 } if 90 idiv + % Rotate specifies *clockwise* rotation! + neg 3 and def + % Stack: pagedict currentpagedict + 1 index /CropBox pget dup {exch pop} if systemdict /UseCropBox known and { + % Set the page size. + 1 index /CropBox pget pop + boxrect 2 array astore /PageSize exch def pop pop + } { + 1 index /MediaBox pget { + % Set the page size. + boxrect 2 array astore /PageSize exch def pop pop + } if + } ifelse + dup /Install .knownget { + % Don't let the Install procedure get more deeply + % nested after every page. + dup type dup /arraytype eq exch /packedarraytype eq or { + dup length 4 eq { + dup 2 get /.pdfshowpage_Install load eq { + 1 get 0 get % previous procedure + } if + } if + } if + } { + { } + } ifelse 1 array astore + 2 index exch /.pdfshowpage_Install load /exec load + 4 packedarray cvx + % Stack: pagedict currentpagedict installproc + /Install exch def + % Stack: pagedict currentpagedict + pop currentdict end setpagedevice +} bind def + +/pdfshowpage_finish { % <pagedict> pdfshowpage_finish - + save /PDFSave exch store + (before exec) VMDEBUG + + .writepdfmarks { + + % Copy the crop box. + dup /CropBox knownoget { + % If the page has been rotated, rotate the CropBox. + mark /CropBox 3 -1 roll + 3 index /Rotate pget { + 90 idiv 1 and 0 ne { + aload pop 4 -2 roll exch 4 2 roll exch 4 array astore + } if + } if + /PAGE pdfmark + } if + + % Copy annotations and links. + dup /Annots knownoget { + 0 1 2 index length 1 sub + { 1 index exch oget + dup /Subtype oget annottypes exch .knownget { exec } { pop } ifelse + } + for pop + } if + + } if % end .writepdfmarks + + % Display the actual page contents. + 6 dict begin + /BXlevel 0 def + /BGDefault currentblackgeneration def + /UCRDefault currentundercolorremoval def + %****** DOESN'T HANDLE COLOR TRANSFER YET ****** + /TRDefault currenttransfer def + matrix currentmatrix 2 dict + 2 index /CropBox knownoget { + boxrect 4 array astore 1 index /ClipRect 3 -1 roll put + } if + dictbeginpage /DefaultMatrix 1 index store setmatrix + dup % for showing annotations below + count /pdfemptycount exch store + gsave + % If the page uses any transparency features, show it within + % a transparency group. + PDFversion 1.4 lt { + showpagecontents + } { + dup pageusestransparency { + % Show the page within a PDF 1.4 device filter. + 0 .pushpdf14devicefilter { + % If the page has a Group, enclose contents in transparency group. + % (Adobe Tech Note 5407, sec 9.2) + dup /Group knownoget { + 1 index /CropBox knownoget not { + 1 index /MediaBox oget + } if .beginformgroup { + showpagecontents + } .internalstopped { + .discardtransparencygroup stop + } if .endtransparencygroup + } { + showpagecontents + } ifelse + } .internalstopped { + % todo: discard + .popdevicefilter stop + } if .popdevicefilter + } { + showpagecontents + } ifelse + } ifelse + grestore + % todo: mixing drawing ops outside the device filter could cause + % problems, for example with the pnga device. + /Annots knownoget { { oforce drawannot } forall } if + endpage + end % scratch dict + (after exec) VMDEBUG + PDFSave restore +} bind def +/showpagecontents { % <pagedict> showpagecontents - + /Contents knownoget not { 0 array } if + dup type /arraytype ne { 1 array astore } if { + oforce false resolvestream pdfopdict .pdfrun + } forall +} bind def +/processcolorspace { % - processcolorspace <colorspace> + % The following is per the PLRM3. + currentdevice 1 dict dup /ProcessColorModel dup put .getdeviceparams + exch pop exch pop + dup type /nametype ne { cvn } if + dup { setcolorspace } .internalstopped { pop /DeviceRGB } if +} bind def + +% ------ Transparency support ------ % + +% Determine whether a page might invoke any transparency features: +% - Group in the page dictionary +% - Non-default ca, CA, or SMask in an ExtGState +% - Form XObject with Group +% - Image XObject with SMask +% ****** DO WE NEED TO LOOK IN RESOURCE DICTS OF OTHER CONTENT STREAMS? ****** +/pageusestransparency { % <pagedict> pageusestransparency <bool> + PDFversion 1.4 lt { + pop false + } { + dup /Group known { + pop true + } { + false exch { + dup resourceusestransparency { pop not exit } if + /Parent knownoget not { exit } if + } loop + } ifelse + } ifelse +} bind def +% Check the Resources of a page or Form. +/resourceusestransparency { % <dict> resourceusestransparency <bool> + { % Use loop to provide an exitable context. + /Resources knownoget not { 0 dict } if + dup /ExtGState knownoget { + false exch { + exch pop oforce + dup /ca knownoget { 1 ne { pop not exit } if } if + dup /CA knownoget { 1 ne { pop not exit } if } if + dup /SMask knownoget { /None ne { pop not exit } if } if + pop + } forall { pop true exit } if + } if + dup /XObject knownoget { + false exch { + exch pop oforce dup /Subtype get + dup /Image eq { 1 index /SMask known { pop pop not exit } if } if + /Form eq { + dup /Group known { pop not exit } if + resourceusestransparency { not exit } if + } { + pop + } ifelse + } forall { pop true exit } if + } if + pop false exit + } loop +} bind def + +end % pdfdict +.setglobal |