pdf_main.ps 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337
  1. % Copyright (C) 1994, 2000 Aladdin Enterprises. All rights reserved.
  2. %
  3. % This software is provided AS-IS with no warranty, either express or
  4. % implied.
  5. %
  6. % This software is distributed under license and may not be copied,
  7. % modified or distributed except as expressly authorized under the terms
  8. % of the license contained in the file LICENSE in this distribution.
  9. %
  10. % For more information about licensing, please refer to
  11. % http://www.ghostscript.com/licensing/. For information on
  12. % commercial licensing, go to http://www.artifex.com/licensing/ or
  13. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  14. % San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  15. % $Id: pdf_main.ps,v 1.100 2005/09/23 18:21:23 ray Exp $
  16. % pdf_main.ps
  17. % PDF file- and page-level operations.
  18. /.setlanguagelevel where { pop 2 .setlanguagelevel } if
  19. .currentglobal true .setglobal
  20. /pdfdict where { pop } { /pdfdict 100 dict def } ifelse
  21. pdfdict begin
  22. % Patch in an obsolete variable used by some third-party software.
  23. /#? false def
  24. % Test whether the current output device handles pdfmark.
  25. /.writepdfmarkdict 1 dict dup /pdfmark null put readonly def
  26. /.writepdfmarks { % - .writepdfmarks <bool>
  27. currentdevice //.writepdfmarkdict .getdeviceparams
  28. mark eq { false } { pop pop true } ifelse
  29. systemdict /DOPDFMARKS known or
  30. } bind def
  31. % For simplicity, we use a single interpretation dictionary for all
  32. % PDF graphics execution, even though this is too liberal.
  33. /pdfopdict mark
  34. objopdict { } forall
  35. drawopdict { } forall
  36. /endstream { exit } bind
  37. (%%EOF) cvn { exit } bind % for filters
  38. % PDF 1.1 operators
  39. /BX { /BXlevel BXlevel 1 add store } bind
  40. /EX { /BXlevel BXlevel 1 sub store } bind
  41. /PS { cvx exec } bind
  42. % PDF 1.2 operators
  43. /BMC { pop } bind
  44. /BDC { pop pop } bind
  45. /EMC { }
  46. /MP { pop } bind
  47. /DP { pop pop } bind
  48. .dicttomark readonly def
  49. % ======================== Main program ======================== %
  50. end % pdfdict
  51. userdict begin
  52. /defaultfontname /Times-Roman def
  53. % Make sure the registered encodings are loaded, so we don't run the risk
  54. % that some of the indices for their names will overflow the packed
  55. % representation. (Yes, this is a hack.)
  56. SymbolEncoding pop
  57. DingbatsEncoding pop
  58. % Redefine 'run' so it recognizes PDF files.
  59. systemdict begin
  60. /.runps /run load def
  61. /run {
  62. dup type /filetype ne { (r) file } if
  63. % skip leading whitespace characters (actually anything less than or equal to <sp>)
  64. { dup ( ) .peekstring not { false exit } if
  65. dup 0 get 32 le { pop dup read pop pop } { true exit } ifelse
  66. } loop
  67. {
  68. (%) eq {
  69. dup ( ) .peekstring {
  70. (%PDF-) eq {
  71. dup (%stdin) (r) file eq {
  72. % Copy PDF from stdin to temporary file then run it.
  73. null (w+) //systemdict /.tempfile get exec exch 3 1 roll
  74. % stack: tempname stdin tempfile
  75. 64000 string
  76. {
  77. % stack: tempname stdin tempfile string
  78. 2 index 1 index readstring
  79. exch 3 index exch writestring
  80. not { exit } if
  81. }
  82. loop
  83. pop exch closefile
  84. % stack: tempname tempfile
  85. dup 0 setfileposition
  86. dup runpdf
  87. closefile deletefile
  88. } {
  89. runpdf
  90. } ifelse
  91. } {
  92. cvx .runps % doesn't start with %PDF-
  93. } ifelse
  94. } {
  95. pop cvx .runps % didn't read 5 characters
  96. } ifelse
  97. } {
  98. cvx .runps % didn't start with %
  99. } ifelse
  100. } {
  101. pop closefile % file was empty
  102. } ifelse
  103. } bind odef
  104. currentdict /runpdfstring .undef
  105. /runpdfbegin { % <file> runpdf -
  106. userdict begin
  107. % It turns out that the PDF interpreter uses memory more
  108. % effectively if it is run under at least one level of save.
  109. % This is counter-intuitive, and we don't understand why it happens,
  110. % but the improvement is significant.
  111. /PDFTopSave save def
  112. 0 setobjectformat
  113. /Page# null def
  114. /Page null def
  115. /DSCPageCount 0 def
  116. /PDFSave null def
  117. GS_PDF_ProcSet begin
  118. pdfdict begin
  119. pdfopen begin
  120. Trailer /Root oget /Pages oget /CropBox knownoget
  121. { oforce_array normrect mark /CropBox 3 -1 roll /PAGES pdfmark
  122. }
  123. if
  124. /FirstPage where
  125. { pop FirstPage dup pdfpagecount gt
  126. { (\nRequested FirstPage is greater than the number of pages in the file: ) print
  127. pdfpagecount = flush
  128. } if
  129. } {
  130. 1
  131. } ifelse
  132. /LastPage where { pop LastPage pdfpagecount .min } { pdfpagecount } ifelse
  133. 1 index 1 index gt
  134. { ( No pages will be processed \(FirstPage > LastPage\).) = flush }
  135. { QUIET not
  136. { (Processing pages ) print 1 index =only ( through ) print dup =only
  137. (.) = flush
  138. }
  139. if
  140. }
  141. ifelse
  142. } bind def
  143. /dopdfpages { % firstpage# lastpage# dopdfpages -
  144. << /PDFScanRules true >> setuserparams % set scanning rules for PDF vs. PS
  145. 1 exch
  146. { dup /Page# exch store
  147. QUIET not { (Page ) print dup == flush } if
  148. pdfgetpage pdfshowpage
  149. } for
  150. << /PDFScanRules null >> setuserparams % restore scanning rules for PS
  151. } bind def
  152. /runpdfend {
  153. Repaired { printrepaired } if
  154. currentdict pdfclose
  155. end % temporary dict
  156. end % pdfdict
  157. end % GS_PDF_ProcSet
  158. PDFTopSave restore
  159. end % userdict
  160. } bind def
  161. /runpdf { % <file> runpdf -
  162. runpdfbegin
  163. dopdfpages
  164. runpdfend
  165. } bind def
  166. end % systemdict
  167. % Redefine the procedure that the C code uses for running piped input.
  168. % It is OK to use { (%stdin) run } here, because a startjob cannot occur.
  169. /.runstdin {
  170. { (%stdin) run } execute0
  171. } bind def
  172. end % userdict
  173. pdfdict begin
  174. % ======================== File parsing ======================== %
  175. % Read the cross-reference and trailer sections.
  176. /traileropdict mark
  177. (<<) cvn { mark } bind
  178. (>>) cvn { { .dicttomark } stopped {
  179. ( **** File has unbalanced >> in trailer.\n) pdfformaterror
  180. } if } bind
  181. ([) cvn { mark } bind % ditto
  182. (]) cvn dup load
  183. % /true true % see .pdfexectoken in pdf_base.ps
  184. % /false false % ibid.
  185. % /null null % ibid.
  186. /R { /resolveR cvx 3 packedarray cvx } bind % see Objects below
  187. /startxref /exit load
  188. .dicttomark readonly def
  189. % Because of EOL conversion, lines with fixed contents might be followed
  190. % by one or more blanks.
  191. /lineeq % <filestr> <conststr> lineeq <bool>
  192. { anchorsearch
  193. { pop { ( ) anchorsearch not { () eq exit } if pop } loop }
  194. { pop false }
  195. ifelse
  196. } bind def
  197. /linene { lineeq not } bind def
  198. % Read original version (pre PDF 1.5) of the xref table.
  199. % Note: The position is the location of 'xref'. The current PDFfile
  200. % position is just after the 'XREF'.
  201. /readorigxref % <pos> readorigxref <trailerdict>
  202. {
  203. pop % We do not need the position.
  204. 0 % Initialize xref table error counter
  205. { PDFfile token pop % first object # or trailer
  206. dup /trailer eq { pop exit } if
  207. PDFfile pdfstring readline pop
  208. token pop % entry count
  209. % remaining must be whitespace only (otherwise this xref Size was invalid.
  210. exch dup length 0 ne {
  211. false 1 index { 32 gt { pop true exit } if } forall {
  212. ( **** Warning: xref subsection header has extra characters.\n)
  213. pdfformaterror
  214. /setxrefentry cvx /syntaxerror signalerror
  215. } if
  216. } if
  217. pop % remove last
  218. % This section might be adding new objects:
  219. % ensure that Objects and Generations are big enough.
  220. % stack: <err count> <first obj> <entry count>
  221. 2 copy add growPDFobjects
  222. { % stack: <err count> <obj num>
  223. % Read xref line
  224. PDFfile 20 string readstring pop % always read 20 chars.
  225. token pop % object position
  226. exch token pop % generation #
  227. exch token pop % n or f
  228. exch % stack: <err count> <obj#> <loc> <gen#> <tag> <remainder of line>
  229. dup length 0 ne {
  230. % check to make sure trailing garbage is just white space
  231. dup { 32 gt { 5 -1 roll 1 add 5 1 roll } if } forall % bump error count on garbage
  232. } if
  233. pop % Stack: <err count> <obj#> <loc> <gen#> <tag>
  234. dup /n eq { % xref line tag is /n
  235. pop % pop dup of line tag
  236. Objects 3 index lget null eq { % later update might have set it
  237. 0 3 1 roll % Set ObjectStream object number = 0
  238. setxrefentry % Save xref entry
  239. 3 -1 roll pop % Remove ObjectStream object onumber
  240. } if
  241. }
  242. { % xref line tag was not /n
  243. /f ne % verify that the tag was /f
  244. { /setxrefentry cvx /syntaxerror signalerror
  245. } if
  246. } ifelse
  247. pop pop % pop <obj location> and <gen num>
  248. % stack: <err count> <obj num>
  249. 1 add % increment object number
  250. } repeat
  251. pop % pop <obj #>
  252. } loop
  253. 0 ne {
  254. ( **** Warning: length of some xref entries is not equal to 20 bytes.\n)
  255. pdfformaterror
  256. } if
  257. PDFfile traileropdict .pdfrun
  258. } bind def
  259. % This dicitonary is used to read the xref dictionary. It should work for
  260. % reading any dictionary. dictlevelcount must contain 0.
  261. /xrefopdict mark
  262. (<<) cvn { /dictlevelcount dictlevelcount 1 add def mark } bind
  263. (>>) cvn { .dicttomark /dictlevelcount dictlevelcount 1 sub def
  264. dictlevelcount 0 eq { exit} if } bind
  265. ([) cvn { mark } bind % ditto
  266. (]) cvn dup load
  267. % /true true % see .pdfexectoken in pdf_base.ps
  268. % /false false % ibid.
  269. % /null null % ibid.
  270. /R { /resolveR cvx 3 packedarray cvx } bind % see Objects below
  271. .dicttomark readonly def
  272. % Get a variable length positive integer value from a stream. A value
  273. % of zero is returned if the count is zero.
  274. /getintn { % <stream> <count> getintn int
  275. 0 exch { 256 mul 1 index read pop add } repeat
  276. exch pop % Discard stream
  277. } bind def
  278. % This array contains handlers for processing the different types of
  279. % entries in the XRef stream.
  280. % Stack: <Xrefdict> <xref stream> <Index array> <pair loc> <obj num>
  281. % <field 2> <field 3>
  282. % The handlers leave the stack unchanged.
  283. /xref15entryhandlers [
  284. { % XRef entry type 0 - free or f type xref entry
  285. % (free ) print
  286. % (obj num: ) print 2 index pdfstring cvs print ( ) print
  287. % (loc: ) print 1 index pdfstring cvs print ( ) print
  288. % (gen: ) print dup === flush
  289. } bind % Do nothing for free xref entries
  290. % XRef entry type 1 - normal or n type xref entry
  291. { % field 2 = obj loc, field 3 = gen num
  292. % (normal ) print
  293. % (obj num: ) print 2 index pdfstring cvs print ( ) print
  294. % (loc: ) print 1 index pdfstring cvs print ( ) print
  295. % (gen: ) print dup === flush
  296. 0 3 1 roll % set stream number = 0
  297. setxrefentry
  298. 3 -1 roll pop % remove stream number
  299. } bind
  300. % XRef entry type 2 - compressed object type xref entry
  301. { % field 2 = object stream num, field 3 = index into object stream
  302. % (Compressed objects: ) print
  303. % (obj num: ) print 2 index pdfstring cvs print ( ) print
  304. % (field 2: ) print 1 index pdfstring cvs print ( ) print
  305. % (field 3: ) print dup === flush
  306. 0 setxrefentry pop % set generation number = 0
  307. } bind
  308. ] def
  309. % Read the PDF 1.5 version of the xref table.
  310. % Note: The position is the location of the start of the dictionary object
  311. % In PDF 1.5, the XRef dictionary also serves as the trailer dictionary
  312. /readpdf15xref % <pos> readpdf15xref <trailerdict>
  313. {
  314. PDFfile exch setfileposition % move to start of object
  315. % Get object number, revision, and 'obj' and discard
  316. PDFfile token pop pop
  317. PDFfile token pop pop
  318. PDFfile token pop pop
  319. % Get the XRef dicitionary
  320. /dictlevelcount 0 def PDFfile xrefopdict .pdfrun
  321. % Verify that we have an XRef dictionary
  322. dup /Type get /XRef ne {
  323. /readpdf15xref cvx /syntaxerror signalerror
  324. } if
  325. % Ensure that we we have room in the objects array, etc.
  326. dup /Size get growPDFobjects
  327. % Create a stream for the XRef data
  328. PDFfile token pop pop % Skip over 'stream'
  329. dup stream false resolvestream
  330. % Stack: <XRefdict> <xref stream>
  331. % The Index array defines the ranges of object numbers in the
  332. % XRef stream. Each value pair is consists of starting object
  333. % number and the count of consecutive objects.
  334. % Get the Index array, if present
  335. 1 index /Index .knownget not { % If no Index array ...
  336. [ 0 3 index /Size get ] % Default = [ 0 Size ]
  337. } if
  338. % Loop through the Index array
  339. 0 2 2 index length 1 sub {
  340. % Get start and end of object range
  341. 2 copy get % Start of the range
  342. dup 3 index 3 index 1 add get % Number of entries in range
  343. % Loop through the range of object numbers
  344. add 1 sub 1 exch { % Form end of range, set increment = 1
  345. % Stack: <Xrefdict> <xref stream> <Index array> <pair loc> <obj num>
  346. % Get xref parameters. Note: The number of bytes for each parameter
  347. % is defined by the entries in the W array.
  348. 4 index /W get aload pop % Get W array values
  349. % The first field indicates type of entry. Get first field value.
  350. % If the num. of bytes for field 1 is 0 then default field value is 1
  351. 3 -1 roll dup 0 eq { pop 1 } { 6 index exch getintn } ifelse
  352. % Get the handler for the xref entry type. We will execute the
  353. % handler after we get the other two field values.
  354. xref15entryhandlers exch get
  355. 3 -1 roll 6 index exch getintn % Get second field
  356. 3 -1 roll 6 index exch getintn % Get third field
  357. 3 -1 roll exec % Execute Xref entry handler
  358. pop pop pop % Remove field values and obj num
  359. } for % Loop through Xref entries
  360. pop % Remove Index array pair loc
  361. } for % Loop through Index array entries
  362. pop pop % Remove Index array and xref stream
  363. } bind def
  364. % Read the cross-reference table.
  365. % <pos> is the position either from the startxref statement or the /Prev
  366. % entry in the prior trailer dictionary.
  367. /readxref % <pos> readxref <trailerdict>
  368. {
  369. PDFoffset add PDFfile exch setfileposition
  370. % In some PDF files, this position actually points to
  371. % white space before the xref line. Skip over this here.
  372. {
  373. PDFfile fileposition PDFfile read pop 32 gt { exit } if pop
  374. } loop
  375. dup % Make copy of the file position (before last char was read).
  376. PDFfile exch setfileposition
  377. % The PDF specification says that the 'xref' must be on a line
  378. % by itself. The code here formerly used readline and linene to
  379. % check this. However, Acrobat Reader only requires the line to
  380. % begin with 'xref', and there are enough applications producing
  381. % non-compliant PDF files that we have to do this too.
  382. PDFfile pdfstring 0 4 getinterval readstring pop
  383. (xref) eq
  384. { readorigxref } % 'xref' -> original xref table
  385. { readpdf15xref } % otherwise assume PDF 1.5 xref stream
  386. ifelse
  387. } bind def
  388. % Open a PDF file and read the header, trailer, and cross-reference.
  389. /pdfopen { % <file> pdfopen <dict>
  390. % Color space substitution in PDF is handled somewhat differently
  391. % than in PostScript. A given device color space will be substituted
  392. % if the corresponding "Default..." entry exists in the Page's
  393. % Resource dictionary (which might be inhereted); there is no
  394. % UseCIEColor to enable/disable color mapping.
  395. %
  396. % This behavior is achieved by always setting UseCIEColor to true
  397. % in the page device dictionary. If the value of this parameter was
  398. % originally false (i.e.: the output device does not perform color
  399. % space substitution by default), the instances DefaultGray,
  400. % DefaultRGB, and DefaultCMYK of the (local) ColorSpace category
  401. % are redefined to be DeviceGray, DeviceRGB, and DeviceCMYK,
  402. % respectively. This is not done if UseCIEColor is true by default,
  403. % as in that case color substitution is presumably desired even
  404. % if the file does not request it.
  405. currentpagedevice /UseCIEColor .knownget dup { pop } if not
  406. { .currentglobal false .setglobal
  407. /DefaultGray { /DeviceGray } cvlit /ColorSpace defineresource pop
  408. /DefaultRGB { /DeviceRGB } cvlit /ColorSpace defineresource pop
  409. /DefaultCMYK { /DeviceCMYK } cvlit /ColorSpace defineresource pop
  410. .setglobal
  411. }
  412. if
  413. pdfopenfile begin
  414. pdfopencache
  415. .writepdfmarks {
  416. % Copy bookmarks (outline) to the output.
  417. Trailer /Root oget /Outlines knownoget {
  418. /First knownoget {
  419. { dup writeoutline /Next knownoget not { exit } if } loop
  420. } if
  421. } if
  422. } if % end .writepdfmarks
  423. currentdict end
  424. } bind def
  425. % Verify that each entry in the xref table is pointing at an object with
  426. % the correct object number and generation number.
  427. /verify_xref % - verify_xref -
  428. { 1 1 Objects llength 1 sub % stack: 1 1 <number of objects - 1>
  429. { % Check if the object is free (i.e. not used). The values in
  430. % Generations is the generation number plus 1. If the value in
  431. % Generations is zero then the object is free.
  432. Generations 1 index lget % Get the genration number
  433. 0 ne { % Skip if object number is free
  434. ObjectStream 1 index lget % Check if object is in objectstream
  435. 0 eq { % We only check objects not in an objectstream
  436. { % Use stop context since we may get an error if object is invalid
  437. dup Objects exch lget % Get the object location
  438. PDFoffset add PDFfile exch setfileposition
  439. true % Stack: <obj num> <true>
  440. PDFfile token pop % Read object number from file
  441. 2 index eq { % Verify object number
  442. PDFfile token pop % Read generation number from file
  443. Generations 3 index % Get specified generaton number
  444. lget 1 sub % Gen numbs are stored with 1 added.
  445. eq { % Verify generation number
  446. PDFfile token pop /obj eq { % Verify 'obj' text
  447. pop false % We have valid object, do not rebuild
  448. } if
  449. } if
  450. } if
  451. } .internalstopped
  452. { true } if % If we stop then we need to rebuild
  453. {
  454. ( **** Warning: File has an invalid xref entry: )
  455. pdfformaterror
  456. pdfstring cvs pdfformaterror
  457. (. Rebuilding xref table.\n) pdfformaterror
  458. search_objects
  459. exit
  460. } if % If the entry is invalid
  461. } if % If not in an object stream
  462. } if % If object entry is not free
  463. pop % Remove object number
  464. } for
  465. } bind odef
  466. /pdfopencache { % - pdfopencache -
  467. % Create and initialize some caches.
  468. /PageCount pdfpagecount def
  469. /PageNumbers PageCount 65534 .min dict def
  470. /PageIndex PageCount 65534 .min array def
  471. } bind def
  472. /pdfopenfile { % <file> pdfopenfile <dict>
  473. pdfdict readonly pop % can't do it any earlier than this
  474. 15 dict begin
  475. /LocalResources 0 dict def
  476. /DefaultQstate //null def % establish binding
  477. /Printed where { pop } {
  478. % Guess whether the output device is a printer.
  479. /Printed currentpagedevice /OutputFile known def
  480. } ifelse
  481. /PSLevel1 where { pop } { /PSLevel1 false def } ifelse
  482. % NB: PDFfile is used outside of the PDF code to determine that a
  483. % PDF job is being processed; to not change or hide this key.
  484. cvlit /PDFfile exch def
  485. /PDFsource PDFfile def
  486. /Repaired false def
  487. currentglobal true .setglobal globaldict begin
  488. /TTFWarnList 0 dict def /UndefProcList 0 dict def
  489. end .setglobal
  490. PDFfile dup 0 setfileposition pdfstring readstring
  491. not {/pdfopen cvx /syntaxerror signalerror} if
  492. (%PDF-) search not {/pdfopen cvx /syntaxerror signalerror} if
  493. length /PDFoffset exch def pop
  494. % some badly formed PDF's (Visioneer) have something other than EOL
  495. % after the version number. If we get an error, shorten the string
  496. % and try again.
  497. false exch % error encountered
  498. { { cvr } stopped
  499. { exch pop true exch 0 1 index length 1 sub dup 0 eq
  500. { pop 0 exit } if % exit if string now empty
  501. getinterval % trim character from right end and retry
  502. }
  503. { exch {
  504. ( **** Warning: PDF version number not followed by EOL.\n)
  505. pdfformaterror
  506. }
  507. if exit
  508. }
  509. ifelse
  510. } loop
  511. /PDFversion exch def
  512. % Read the last cross-reference table.
  513. count /pdfemptycount exch def
  514. /Trailer << >> def % Initialize to an emptry dict.
  515. { initPDFobjects findxref readxref } .internalstopped {
  516. recover_xref_data % Read failed. Attempt to recover xref data.
  517. search_trailer % Search for the primary trailer
  518. } {
  519. /Trailer exch def % Save trailer dict after first xref table
  520. % Read any previous cross-reference tables. When we are done,
  521. % verify that the entries in the xref tables are valid if NoVerifyXref
  522. % is not defined.
  523. Trailer
  524. { /Prev knownoget not { % If no previous xref table then ...
  525. /NoVerifyXref where { pop } { verify_xref } ifelse exit
  526. } if
  527. { readxref } .internalstopped {
  528. recover_xref_data % Read failed. Attempt to recover xref data.
  529. exit % Exit loop since recover gets all obj data.
  530. } if % If readxref stopped
  531. % The PDF spec. says that each trailer dict should contain the required
  532. % entries. However we have seen a PDF file that only has a Prev entry in
  533. % the initial trailer dict. Acrobat complains but it accepts these files.
  534. % To work with these files, we are copying any entries which we find in
  535. % a previous trailer dict which are not present in the initial dict.
  536. dup {
  537. Trailer 2 index known {
  538. pop pop % discard if key already present
  539. } {
  540. Trailer 3 1 roll put % add key if not present
  541. } ifelse
  542. } forall
  543. } loop % Loop to previous trailer
  544. } ifelse % Ifelse readxref stopped
  545. Trailer /Encrypt knownoget {
  546. pop
  547. pdf_process_Encrypt % signal error
  548. } if
  549. currentdict end
  550. } bind def
  551. % Look for [\r\n]%%EO from the current position of the file.
  552. % Return the position of %%EO if found or -1 .
  553. /findeof { % <file> find_eof <file> <position>
  554. -1 exch
  555. {
  556. dup bytesavailable 4 lt { exit } if
  557. dup 0 (%%EO) /SubFileDecode filter flushfile
  558. dup dup fileposition 5 sub setfileposition
  559. dup 5 string readstring not { pop exit } if
  560. dup (\r%%EO) eq exch (\n%%EO) eq or {
  561. dup fileposition 4 sub
  562. 3 1 roll exch pop
  563. } if
  564. } loop
  565. exch
  566. } bind def
  567. % Skip backward over the %%EOF at the end of the PDF file, and read
  568. % the preceding startxref line. The PDF specification unambiguously
  569. % requires that the %%EOF appear on a line by itself, and that the
  570. % startxref and the following position value appear on separate lines;
  571. % however, some applications truncate the %%EOF to %%EO, and/or put the
  572. % startxref and the following value on the same line.
  573. % There seems to be no limit on the amount of garbage that can be
  574. % appended to the PDF file. Current record (60K) belongs to
  575. % PDF-Out (v 2.0 - 35). We start the search for %%EO from the last 1024
  576. % bytes and continue from the beginning of the file.
  577. /findxref { % - findxref <xrefpos>
  578. PDFfile dup dup dup 0 setfileposition bytesavailable
  579. dup /PDFfilelen exch def
  580. % Find the last %%EOF string (within 1024 bytes)
  581. 1024 sub PDFoffset .max
  582. setfileposition findeof % search the last 1024 bytes
  583. dup 0 le {
  584. pop
  585. dup PDFoffset setfileposition findeof % search from the beginnibg
  586. dup 0 le {
  587. ( **** Error: Cannot find a %%EOF marker anywhere in the file.\n)
  588. pdfformaterror
  589. /findxref cvx /syntaxerror signalerror
  590. } if
  591. } if
  592. dup 3 1 roll setfileposition
  593. % Stack: eofpos
  594. % Check for whether this is, in fact, a valid PDF file.
  595. dup PDFfilelen exch sub dup dup 7 gt exch 5 lt or {
  596. pop true
  597. } {
  598. string PDFfile exch readstring pop
  599. dup (%%EOF\n) eq exch dup (%%EOF\r) eq
  600. exch dup (%%EOF\r\n) eq exch (%%EOF) eq or or or not
  601. } ifelse {
  602. ( **** Warning: File has a corrupted %%EOF marker, or garbage after %%EOF.\n)
  603. pdfformaterror
  604. } if
  605. PDFfile exch setfileposition
  606. % Now read the startxref and xref start position.
  607. prevline token not { null } if dup type /integertype eq {
  608. exch pop cvi % xref start position
  609. exch PDFfile exch setfileposition
  610. prevline dup (startxref) linene {
  611. % startxref not on a line by itself. We have found PDF from
  612. % www.verypdf.com in which the startxref was on the same line as
  613. % the end of trailer dictionary. Check for this. Note: This
  614. % violates the spec.
  615. dup (startxref) search {
  616. % found startxref - print warning
  617. pop pop pop % clear strings from search
  618. ( **** Warning: format of the startxref line in this file is invalid.\n)
  619. pdfformaterror
  620. } { % no startxref - we have a problem.
  621. /findxref cvx /syntaxerror signalerror
  622. } ifelse
  623. } if
  624. pop pop
  625. } { % else, this file has 'startxref #####' format
  626. (startxref) ne { /findxref cvx /syntaxerror signalerror } if
  627. cvi % xref start position
  628. ( **** Warning: format of the startxref line in this file is invalid.\n)
  629. pdfformaterror
  630. exch PDFfile exch setfileposition
  631. } ifelse
  632. } bind def
  633. /stderrfile (%stderr) (w) file def
  634. /stderrprint { % <string> stderrprint -
  635. //stderrfile dup 3 -1 roll writestring flushfile
  636. } bind def
  637. /pdfformaterror { % <string> pdfformaterror -
  638. stderrprint
  639. /Repaired true store
  640. } bind def
  641. /knownoget_safe
  642. { 2 copy knownoget { 3 1 roll pop pop //true } { pop pop //false } ifelse
  643. } odef
  644. /printProducer {
  645. Trailer /Info { knownoget_safe } stopped { pop pop false } if {
  646. /Producer knownoget not { null } if
  647. } {
  648. null
  649. } ifelse
  650. dup null eq {
  651. pop
  652. } {
  653. ( **** The file was produced by: \n **** >>>> ) stderrprint
  654. % Handle a Unicode Producer.
  655. (\376\377) anchorsearch {
  656. pop dup length 2 idiv string 0 1 2 index length 1 sub {
  657. % Stack: origstr newstr i
  658. 1 index exch 3 index 1 index 2 mul 1 add get put
  659. } for exch pop
  660. } if
  661. stderrprint
  662. ( <<<<\n) stderrprint
  663. } ifelse
  664. } bind def
  665. % The TTFWarnList is the list of all TrueType fonts that were not embedded.
  666. % The UndefProcList collects noisy warnings.
  667. % This gets rid of many multiple warnings from pdf_font.ps
  668. /printCollectedWarnings {
  669. TTFWarnList length 0 gt {
  670. (\n **** Warning: Fonts with Subtype = /TrueType should be embedded.\n)
  671. stderrprint
  672. ( The following fonts were not embedded:\n)
  673. stderrprint
  674. [ TTFWarnList { pop .namestring (\t\t\t) exch concatstrings (\n) concatstrings } forall ]
  675. { lt } .sort { stderrprint } forall
  676. } if
  677. UndefProcList length 0 gt {
  678. (\n **** Embedded font uses undefined procedure\(s\): ) stderrprint
  679. UndefProcList {
  680. exch .namestring stderrprint ( ) stderrprint
  681. =string cvs stderrprint ( times, ) stderrprint
  682. } forall
  683. (\n) stderrprint
  684. } if
  685. } bind def
  686. /printrepaired {
  687. printCollectedWarnings
  688. (\n **** This file had errors that were repaired or ignored.\n)
  689. stderrprint
  690. printProducer
  691. ( **** Please notify the author of the software that produced this\n)
  692. stderrprint
  693. ( **** file that it does not conform to Adobe's published PDF\n)
  694. stderrprint
  695. ( **** specification.\n\n)
  696. stderrprint
  697. } bind def
  698. % Write the outline structure for a file. Uses linkdest (below).
  699. % omit links to pages that don't exist.
  700. /writeoutline % <outlinedict> writeoutline -
  701. { mark
  702. 0 2 index /First knownoget
  703. { { exch 1 add exch /Next knownoget not { exit } if } loop }
  704. if
  705. % stack: dict mark count
  706. dup 0 eq
  707. { pop 1 index }
  708. { 2 index /Count knownoget { 0 lt { neg } if } if
  709. /Count exch 3 index
  710. }
  711. ifelse { linkdest } stopped
  712. {
  713. cleartomark % ignore this link
  714. ( **** Warning: Outline has invalid link that was discarded.\n)
  715. pdfformaterror
  716. } {
  717. /Title oget /Title exch /OUT pdfmark
  718. }
  719. ifelse
  720. /First knownoget
  721. { { dup writeoutline /Next knownoget not { exit } if } loop }
  722. if
  723. } bind def
  724. % Close a PDF file.
  725. /pdfclose % <dict> pdfclose -
  726. { begin
  727. PDFfile closefile
  728. end
  729. } bind def
  730. % ======================== Page accessing ======================== %
  731. % Get a (possibly inherited) attribute of a page.
  732. /pget % <pagedict> <key> pget <value> -true-
  733. % <pagedict> <key> pget -false-
  734. { 2 copy knownoget
  735. { exch pop exch pop true
  736. }
  737. { exch /Parent knownoget
  738. { exch pget }
  739. { pop false }
  740. ifelse
  741. }
  742. ifelse
  743. } bind def
  744. % Get the value of a resource on a given page.
  745. /rget { % <resname> <pagedict> <restype> rget <value> -true-
  746. % <resname> <pagedict> <restype> rget -false-
  747. LocalResources 1 index knownoget {
  748. 3 index knownoget
  749. } {
  750. false
  751. } ifelse {
  752. exch pop exch pop exch pop true
  753. } {
  754. exch /Resources pget {
  755. exch knownoget { exch knownoget } { pop false } ifelse
  756. } {
  757. pop pop false
  758. } ifelse
  759. } ifelse
  760. } bind def
  761. % Get the total number of pages in the document.
  762. /pdfpagecount % - pdfpagecount <int>
  763. { Trailer /Root oget /Pages oget /Count oget
  764. } bind def
  765. % Find the N'th page of the document by iterating through the Pages tree.
  766. % The first page is numbered 1.
  767. /pdffindpageref { % <int> pdffindpage <objref>
  768. dup Trailer /Root oget /Pages get
  769. { % We should be able to tell when we reach a leaf
  770. % by finding a Type unequal to /Pages. Unfortunately,
  771. % some files distributed by Adobe lack the Type key
  772. % in some of the Pages nodes! Instead, we check for Kids.
  773. dup oforce /Kids knownoget not { exit } if
  774. exch pop null
  775. 0 1 3 index length 1 sub {
  776. 2 index exch get
  777. dup oforce dup /Kids known { /Count oget } { pop 1 } ifelse
  778. % Stack: index kids null noderef count
  779. dup 5 index ge { pop exch pop exit } if
  780. 5 -1 roll exch sub 4 1 roll pop
  781. } for exch pop
  782. % Stack: index null|noderef
  783. dup null eq { pop pop 1 null exit } if
  784. } loop
  785. % Stack: index countleft noderef
  786. 1 index 1 ne { pop pop /pdffindpage cvx /rangecheck signalerror } if
  787. exch pop
  788. PageIndex 2 index 1 sub 65533 .min 2 index oforce put
  789. PageNumbers 1 index oforce 3 index dup 65534 le
  790. { put }
  791. { pop pop pop } % don't store more than 65534 pagenumbers
  792. ifelse
  793. exch pop
  794. } bind def
  795. /pdffindpage { % <int> pdffindpage <pagedict>
  796. pdffindpageref oforce
  797. } bind def
  798. % Find the N'th page of the document.
  799. % The first page is numbered 1.
  800. /pdfgetpage % <int> pdfgetpage <pagedict>
  801. { PageIndex 1 index 1 sub dup 65533 lt
  802. { get }
  803. { pop pop null }
  804. ifelse
  805. dup null ne
  806. { exch pop oforce }
  807. { pop pdffindpage }
  808. ifelse
  809. } bind def
  810. % Find the page number of a page object (inverse of pdfgetpage).
  811. /pdfpagenumber % <pagedict> pdfpagenumber <int>
  812. { % We use the simplest and stupidest of all possible algorithms....
  813. PageNumbers 1 index .knownget
  814. { exch pop
  815. }
  816. { 1 1 PageCount 1 add % will give a rangecheck if not found
  817. { dup pdfgetpage oforce 2 index eq { exit } if pop
  818. }
  819. for exch pop
  820. }
  821. ifelse
  822. } bind def
  823. % Arrange the four elements that define a rectangle into a 'normal' order.
  824. /normrect_elems % <x1> <y1> <x2> <y2> normrect_elems <llx> <lly> <urx> <ury>
  825. {
  826. exch 4 1 roll % <x2> <x1> <y1> <y2>
  827. 2 copy gt { exch } if % <x2> <x1> <lly> <ury>
  828. 4 2 roll 2 copy lt { exch } if % <lly> <ury> <urx> <llx>
  829. 4 1 roll exch % <llx> <lly> <urx> <ury>
  830. } bind def
  831. % Arrange a rectangle into a 'normal' order. I.e the lower left corner
  832. % followed by the upper right corner.
  833. /normrect % <rect> normrect <rect>
  834. {
  835. aload pop normrect_elems 4 array astore
  836. } bind def
  837. /boxrect % <llx> <lly> <urx> <ury> boxrect <x> <y> <w> <h>
  838. { exch 3 index sub exch 2 index sub
  839. } bind def
  840. /resolvedest { % <name|string|other> resolvedest <other|null>
  841. dup type /nametype eq {
  842. Trailer /Root oget /Dests knownoget {
  843. exch knownoget not { null } if
  844. } {
  845. pop null
  846. } ifelse
  847. } {
  848. dup type /stringtype eq {
  849. Trailer /Root oget /Names knownoget {
  850. /Dests knownoget {
  851. exch nameoget
  852. } {
  853. pop null
  854. } ifelse
  855. } {
  856. pop null
  857. } ifelse
  858. } if
  859. } ifelse
  860. } bind def
  861. /linkdest { % <link|outline> linkdest
  862. % ([/Page <n>] /View <view> | ) <link|outline>
  863. dup /Dest knownoget
  864. { resolvedest
  865. dup type /dicttype eq { /D knownoget not { null } if } if
  866. dup null eq
  867. { pop }
  868. { dup 0 oget
  869. dup type /dicttype eq {
  870. dup /Type knownoget {
  871. /Page eq {
  872. pdfpagenumber
  873. } if
  874. } if
  875. } if
  876. dup type /integertype ne
  877. { pop }
  878. { /Page exch 4 -2 roll }
  879. ifelse
  880. dup length 1 sub 1 exch getinterval /View exch 3 -1 roll
  881. }
  882. ifelse
  883. }
  884. if
  885. } bind def
  886. % <pagedict> mark ... -proc- -
  887. /namedactions 8 dict dup begin
  888. /FirstPage {
  889. /Page 1 3 -1 roll
  890. } def
  891. /LastPage {
  892. counttomark 2 add index pdfpagecount /Page exch 3 -1 roll
  893. } def
  894. /NextPage {
  895. counttomark 2 add index pdfpagenumber 1 add /Page exch 3 -1 roll
  896. } def
  897. /PrevPage {
  898. counttomark 2 add index pdfpagenumber 1 sub /Page exch 3 -1 roll
  899. } def
  900. end readonly def
  901. % <pagedict> <annotdict> -proc- -
  902. /annottypes 5 dict dup begin
  903. /Text {
  904. mark exch
  905. { /Rect /Open /Contents }
  906. { 2 copy knownoget { 3 -1 roll } { pop } ifelse }
  907. forall pop /ANN pdfmark
  908. } bind def
  909. /Link {
  910. mark exch
  911. dup /C knownoget { /Color exch 3 -1 roll } if
  912. { /Rect /Border }
  913. { 2 copy knownoget { 3 -1 roll } { pop } ifelse }
  914. forall dup /A knownoget {
  915. dup /URI known {
  916. /A mark 3 2 roll % <<>> /A [ <<action>>
  917. { oforce } forall
  918. .dicttomark
  919. 3 2 roll
  920. } {
  921. dup /D knownoget {
  922. exch pop exch dup length dict copy dup /Dest 4 -1 roll put
  923. } {
  924. /N knownoget { % Assume /S /Named
  925. namedactions exch .knownget { exec } if
  926. } if
  927. } ifelse
  928. } ifelse
  929. } if
  930. linkdest pop /LNK pdfmark
  931. } bind def
  932. end readonly def
  933. % **** The following procedure should not be changed to allow clients
  934. % **** to directly interface with the constituent procedures. GSview
  935. % **** and some Artifex customers rely on the pdfshowpage_init,
  936. % **** pdfshowpage_setpage, pdfshowpage_finish so all logic should be
  937. % **** implemented in one of those three procedures.
  938. /pdfshowpage % <pagedict> pdfshowpage -
  939. { dup /Page exch store
  940. pdfshowpage_init
  941. pdfshowpage_setpage
  942. pdfshowpage_finish
  943. } bind def
  944. /pdfpagecontents % <pagedict> pdfpagecontents <contents>
  945. { } bind def
  946. /pdfshowpage_init % <pagedict> pdfshowpage_init <pagedict>
  947. { /DSCPageCount DSCPageCount 1 add store
  948. } bind def
  949. /.pdfshowpage_Install { % <pagedict> [<prevproc>] .pdfshowpage_Install -
  950. exch
  951. % We would like to clip to the CropBox here, but the subsequent
  952. % initgraphics would override it. Instead, we have to handle it
  953. % in graphicsbeginpage.
  954. dup /CropBox pget dup {exch pop} if systemdict /UseCropBox known and {
  955. dup /CropBox pget pop
  956. } {
  957. dup /MediaBox pget pop % There has to be a MediaBox
  958. } ifelse
  959. % stack: [<prevproc>] <pagedict> <Crop|Media Box>
  960. exch pop oforce_array normrect % done with the pagedict
  961. systemdict /PDFFitPage known {
  962. PDFDEBUG { (Fiting PDF to imageable area of the page.) = flush } if
  963. currentpagedevice /.HWMargins get aload pop
  964. currentpagedevice /PageSize get aload pop
  965. 3 -1 roll sub 3 1 roll exch sub exch
  966. % stack: [<prevproc>] <pagedict> <Crop|Media Box> Xmin Ymin Xmax Ymax
  967. PDFDEBUG { ( Translate up by [ ) print 3 index =print (, ) print 2 index =print ( ]) = flush } if
  968. 3 index 3 index translate % move origin up to imageable area
  969. 2 index sub exch 3 index sub exch 4 2 roll pop pop
  970. % stack: [Box] XImageable YImageable
  971. 2 index aload pop 2 index sub exch 3 index sub exch 4 2 roll pop pop
  972. % stack: [Box] XImageable YImageable XBox YBox
  973. 3 -1 roll exch div 3 1 roll div .min
  974. PDFDEBUG { ( Scale by ) print dup = flush } if
  975. dup scale
  976. } if
  977. % Now translate to the origin given in the Crop|Media Box
  978. dup 0 get neg exch 1 get neg translate
  979. 0 get
  980. exec
  981. } bind def
  982. /pdfshowpage_setpage { % <pagedict> pdfshowpage_setpage <pagedict>
  983. 5 dict begin % for setpagedevice
  984. % Stack: pagedict
  985. % UseCIEColor is always true for PDF; see the comment in runpdf above
  986. /UseCIEColor true def
  987. currentpagedevice /Orientation 2 index /Rotate pget not { 0 } if 90 idiv
  988. % Rotate specifies *clockwise* rotation!
  989. neg 3 and def
  990. % Stack: pagedict currentpagedict
  991. 1 index /CropBox pget dup {exch pop} if systemdict /UseCropBox known and {
  992. % Set the page size.
  993. 1 index /CropBox pget pop oforce_elems normrect_elems boxrect
  994. 2 array astore /PageSize exch def pop pop
  995. } {
  996. 1 index /MediaBox pget {
  997. % Set the page size.
  998. oforce_elems normrect_elems boxrect
  999. 2 array astore /PageSize exch def pop pop
  1000. } if
  1001. } ifelse
  1002. % Don't change the page size if we are going to fit the PDF to the page
  1003. systemdict /PDFFitPage known { currentdict /PageSize undef } if
  1004. % Let the device know if we will be using PDF 1.4 transparency.
  1005. % The clist logic may need to adjust the size of bands.
  1006. 1 index pageusestransparency /PageUsesTransparency exch def
  1007. dup /Install .knownget {
  1008. % Don't let the Install procedure get more deeply
  1009. % nested after every page.
  1010. dup type dup /arraytype eq exch /packedarraytype eq or {
  1011. dup length 4 eq {
  1012. dup 2 get /.pdfshowpage_Install load eq {
  1013. 1 get 0 get % previous procedure
  1014. } if
  1015. } if
  1016. } if
  1017. } {
  1018. { }
  1019. } ifelse 1 array astore
  1020. 2 index exch /.pdfshowpage_Install load /exec load
  1021. 4 packedarray cvx
  1022. % Stack: pagedict currentpagedict installproc
  1023. /Install exch def
  1024. % Stack: pagedict currentpagedict
  1025. pop currentdict end setpagedevice
  1026. } bind def
  1027. /pdfshowpage_finish { % <pagedict> pdfshowpage_finish -
  1028. save /PDFSave exch store
  1029. /PDFdictstackcount countdictstack store
  1030. (before exec) VMDEBUG
  1031. % set up color space substitution (this must be inside the page save)
  1032. pdfshowpage_setcspacesub
  1033. .writepdfmarks {
  1034. % Copy the crop box.
  1035. dup /CropBox knownoget {
  1036. oforce_array normrect
  1037. % .pdfshowpage_Install translates the origin -
  1038. % do same here with the CropBox.
  1039. 1 index /CropBox pget dup {exch pop} if systemdict /UseCropBox known and {
  1040. 1 index /CropBox pget pop
  1041. } {
  1042. 1 index /MediaBox pget pop % There has to be a MediaBox
  1043. } ifelse
  1044. oforce_array normrect
  1045. dup 0 get exch 1 get % [] tx ty
  1046. 2 index 0 get 2 index sub 3 index exch 0 exch put
  1047. 2 index 2 get 2 index sub 3 index exch 2 exch put
  1048. 2 index 1 get 1 index sub 3 index exch 1 exch put
  1049. 2 index 3 get 1 index sub 3 index exch 3 exch put
  1050. pop pop
  1051. % If the page has been rotated, rotate the CropBox.
  1052. mark /CropBox 3 -1 roll
  1053. 3 index /Rotate pget {
  1054. 90 idiv 1 and 0 ne {
  1055. aload pop 4 -2 roll exch 4 2 roll exch 4 array astore
  1056. } if
  1057. } if
  1058. /PAGE pdfmark
  1059. } if
  1060. % Copy annotations and links.
  1061. dup /Annots knownoget {
  1062. 0 1 2 index length 1 sub
  1063. { 1 index exch oget
  1064. dup /Subtype oget annottypes exch .knownget { exec } { pop } ifelse
  1065. }
  1066. for pop
  1067. } if
  1068. } if % end .writepdfmarks
  1069. % Display the actual page contents.
  1070. 6 dict begin
  1071. /BXlevel 0 def
  1072. /BGDefault currentblackgeneration def
  1073. /UCRDefault currentundercolorremoval def
  1074. %****** DOESN'T HANDLE COLOR TRANSFER YET ******
  1075. /TRDefault currenttransfer def
  1076. matrix currentmatrix 2 dict
  1077. 2 index /CropBox knownoget {
  1078. oforce_elems normrect_elems boxrect
  1079. 4 array astore 1 index /ClipRect 3 -1 roll put
  1080. } if
  1081. dictbeginpage setmatrix
  1082. /DefaultQstate qstate store
  1083. dup % for showing annotations below
  1084. count 1 sub /pdfemptycount exch store
  1085. % If the page uses any transparency features, show it within
  1086. % a transparency group.
  1087. dup pageusestransparency dup /PDFusingtransparency exch def {
  1088. % Show the page within a PDF 1.4 device filter.
  1089. 0 .pushpdf14devicefilter {
  1090. /DefaultQstate qstate store % device has changed -- reset DefaultQstate
  1091. % If the page has a Group, enclose contents in transparency group.
  1092. % (Adobe Tech Note 5407, sec 9.2)
  1093. dup /Group knownoget {
  1094. 1 index /CropBox knownoget not {
  1095. 1 index /MediaBox pget pop
  1096. } if oforce_array normrect .beginformgroup {
  1097. showpagecontents
  1098. } stopped {
  1099. .discardtransparencygroup stop
  1100. } if .endtransparencygroup
  1101. } {
  1102. showpagecontents
  1103. } ifelse
  1104. } stopped {
  1105. % todo: discard
  1106. .poppdf14devicefilter
  1107. /DefaultQstate qstate store % device has changed -- reset DefaultQstate
  1108. stop
  1109. } if .poppdf14devicefilter
  1110. /DefaultQstate qstate store % device has changed -- reset DefaultQstate
  1111. } {
  1112. showpagecontents
  1113. } ifelse
  1114. % check for extra garbage on the ostack and clean it up
  1115. count pdfemptycount sub dup 0 ne {
  1116. ( **** File did not complete the page properly and may be damaged.\n)
  1117. pdfformaterror
  1118. { pop } repeat
  1119. } {
  1120. pop
  1121. } ifelse
  1122. % todo: mixing drawing ops outside the device filter could cause
  1123. % problems, for example with the pnga device.
  1124. /Annots knownoget { { oforce drawannot } forall } if
  1125. endpage
  1126. end % scratch dict
  1127. % Some PDF files don't have matching q/Q (gsave/grestore) so we need
  1128. % to clean up any left over dicts from the dictstack
  1129. countdictstack PDFdictstackcount sub dup 0 ne {
  1130. ( **** Warning: File has imbalanced q/Q operators \(too many q's\)\n)
  1131. pdfformaterror
  1132. { end } repeat
  1133. } {
  1134. pop
  1135. } ifelse
  1136. (after exec) VMDEBUG
  1137. Repaired % pass Repaired state around the restore
  1138. PDFSave restore
  1139. /Repaired exch def
  1140. } bind def
  1141. /showpagecontents { % <pagedict> showpagecontents -
  1142. gsave % preserve gstate for Annotations later
  1143. /Contents knownoget not { 0 array } if
  1144. dup type /arraytype ne { 1 array astore } if {
  1145. oforce false resolvestream pdfopdict .pdfrun
  1146. } forall
  1147. grestore
  1148. } bind def
  1149. /processcolorspace { % - processcolorspace <colorspace>
  1150. % The following is per the PLRM3.
  1151. currentdevice 1 dict dup /ProcessColorModel dup put .getdeviceparams
  1152. exch pop exch pop
  1153. dup type /nametype ne { cvn } if
  1154. dup { setcolorspace } .internalstopped { pop /DeviceRGB } if
  1155. } bind def
  1156. % ------ Transparency support ------ %
  1157. % Define minimum PDF version for checking for transparency features.
  1158. % Transparency is a 1.4 feature however we have seen files that claimed
  1159. % to be PDF 1.3 with transparency features.
  1160. /PDFtransparencyversion 1.3 def
  1161. % Determine whether a page might invoke any transparency features:
  1162. % - Non-default BM, ca, CA, or SMask in an ExtGState
  1163. % - Image XObject with SMask
  1164. % Note: we deliberately don't check to see whether a Group is defined,
  1165. % because Adobe Illustrator 10 (and possibly other applications) define
  1166. % a page-level group whether transparency is actually used or not.
  1167. % Ignoring the presence of Group is justified because, in the absence
  1168. % of any other transparency features, they have no effect.
  1169. /pageusestransparency { % <pagedict> pageusestransparency <bool>
  1170. PDFversion PDFtransparencyversion lt NOTRANSPARENCY or {
  1171. pop false
  1172. } {
  1173. false exch {
  1174. 4 dict 1 index resourceusestransparency { pop not exit } if
  1175. /Parent knownoget not { exit } if
  1176. } loop
  1177. } ifelse
  1178. } bind def
  1179. % Check the Resources of a page or Form. Check for loops in the resource chain.
  1180. /resourceusestransparency { % <dict> <dict> resourceusestransparency <bool>
  1181. { % Use loop to provide an exitable context.
  1182. /Resources knownoget not { 0 dict } if
  1183. 2 copy known {
  1184. ( **** File has circular references in resource dictionaries.\n)
  1185. pdfformaterror
  1186. pop false exit
  1187. } if
  1188. 2 copy dup put
  1189. dup /ExtGState knownoget {
  1190. false exch {
  1191. exch pop oforce
  1192. dup /BM knownoget { dup /Normal ne exch /Compatible ne and
  1193. { pop not exit } if
  1194. } if
  1195. dup /ca knownoget { 1 ne { pop not exit } if } if
  1196. dup /CA knownoget { 1 ne { pop not exit } if } if
  1197. dup /SMask knownoget { /None ne { pop not exit } if } if
  1198. pop
  1199. } forall { pop true exit } if
  1200. } if
  1201. dup /XObject knownoget {
  1202. false exch {
  1203. exch pop oforce dup /Subtype get
  1204. dup /Image eq { 1 index /SMask known { pop pop not exit } if } if
  1205. /Form eq {
  1206. 3 index exch resourceusestransparency { not exit } if
  1207. } {
  1208. pop
  1209. } ifelse
  1210. } forall { pop true exit } if
  1211. } if
  1212. pop false exit
  1213. } loop
  1214. exch pop
  1215. } bind def
  1216. % ------ ColorSpace substitution support ------ %
  1217. %
  1218. % <pagedict> pdfshowpage_setcspacesub <pagedict>
  1219. %
  1220. % Set up color space substitution for a page. Invocations of this procedure
  1221. % must be bracketed by the save/restore operation for the page, to avoid
  1222. % unintended effects on other pages.
  1223. %
  1224. % If any color space substitution is used, and the current color space is a
  1225. % device dependent color space, make sure the current color space is updated.
  1226. % There is an optimization in the setcolorspace pseudo-operator that does
  1227. % nothing if both the current and operand color spaces are the same. For
  1228. % PostScript this optimization is disabled if the UseCIEColor page device
  1229. % parameter is true. This is not the case for PDF, as performance suffers
  1230. % significantly on some PDF files if color spaces are set repeatedly. Hence,
  1231. % if color space substitution is to be used, and the current color space
  1232. % is a device dependent color space, we must make sure to "transition" the
  1233. % current color space.
  1234. %
  1235. /pdfshowpage_setcspacesub
  1236. {
  1237. false
  1238. { /DefaultGray /DefaultRGB /DefaultCMYK }
  1239. {
  1240. dup 3 index /ColorSpace //rget exec
  1241. { resolvecolorspace /ColorSpace defineresource pop }
  1242. { pop }
  1243. ifelse
  1244. }
  1245. forall
  1246. % if using color space substitution, "transition" the current color space
  1247. {
  1248. currentcolorspace dup length 1 eq % always an array
  1249. {
  1250. 0 get
  1251. dup /DeviceGray eq 1 index /DeviceRGB eq or 1 index /DeviceCMYK or
  1252. { /Pattern setcolorspace setcolorspace }
  1253. { pop }
  1254. ifelse
  1255. }
  1256. { pop }
  1257. if
  1258. }
  1259. if
  1260. }
  1261. bind def
  1262. end % pdfdict
  1263. .setglobal