gs_lev2.ps 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922
  1. % Copyright (C) 1990, 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: gs_lev2.ps,v 1.38 2005/10/04 17:51:52 ray Exp $
  16. % Initialization file for Level 2 functions.
  17. % When this is run, systemdict is still writable,
  18. % but (almost) everything defined here goes into level2dict.
  19. level2dict begin
  20. % ------ System and user parameters ------ %
  21. % User parameters must obey save/restore, and must also be maintained
  22. % per-context. We implement the former, and some of the latter, here
  23. % with PostScript code. NOTE: our implementation assumes that user
  24. % parameters change only as a result of setuserparams -- that there are
  25. % no user parameters that are ever changed dynamically by the interpreter
  26. % (although the interpreter may adjust the value presented to setuserparams)
  27. %
  28. % There are two types of user parameters: those which are actually
  29. % maintained in the interpreter, and those which exist only at the
  30. % PostScript level. We maintain the current state of both types in
  31. % a read-only local dictionary named userparams, defined in systemdict.
  32. % In a multi-context system, each context has its own copy of this
  33. % dictionary. In addition, there is a constant dictionary named
  34. % psuserparams where each key is the name of a user parameter that exists
  35. % only in PostScript and the value is a procedure to check that the value
  36. % is legal: setuserparams uses this for checking the values.
  37. % setuserparams updates userparams explicitly, in addition to setting
  38. % any user parameters in the interpreter; thus we can use userparams
  39. % to reset those parameters after a restore or a context switch.
  40. % NOTE: the name userparams is known to the interpreter, and in fact
  41. % the interpreter creates the userparams dictionary.
  42. % Check parameters that are managed at the PostScript level.
  43. /.checkparamtype { % <newvalue> <type> .checkparamtype <bool>
  44. exch type eq
  45. } .bind def
  46. /.checksetparams { % <newdict> <opname> <checkdict>
  47. % .checksetparams <newdict>
  48. 2 index {
  49. % Stack: newdict opname checkdict key newvalue
  50. 3 copy 3 1 roll .knownget {
  51. exec not {
  52. pop pop pop load /typecheck signalerror
  53. } if
  54. dup type /stringtype eq {
  55. dup rcheck not {
  56. pop pop pop load /invalidaccess signalerror
  57. } if
  58. } if
  59. } {
  60. pop
  61. } ifelse pop pop
  62. } forall pop pop
  63. } .bind def % not odef, shouldn't reset stacks
  64. % currentuser/systemparams creates and returns a dictionary in the
  65. % current VM. The easiest way to make this work is to copy any composite
  66. % PostScript-level parameters to global VM. Currently we have strings
  67. % as well as arrays. For arrays, we also need to copy any contents that
  68. % are in VM. Also copying string parameters insures the contents won't
  69. % be changed. Also be careful to preserve 'executable' state.
  70. /.copyparam { % <value> .copyparam <value'>
  71. dup type /arraytype eq {
  72. .currentglobal true .setglobal exch
  73. dup wcheck exch dup xcheck exch % original attributes
  74. dup length array exch dup { % stack: destination_array original_array original_array
  75. dup type /arraytype eq {
  76. dup 2 index ne { % avoid recursion
  77. .copyparam % recurse to handle composite array elements
  78. } {
  79. % this array self referenced, do it again (yuk!)
  80. pop 1 index % get copy of destination array
  81. } ifelse
  82. } {
  83. dup type /stringtype eq {
  84. .copyparam
  85. } if
  86. }
  87. ifelse 3 1 roll % keep arrays on top
  88. } forall pop astore
  89. exch { cvx } if % set executable state
  90. exch not { readonly } if % set readonly attribute as original
  91. exch .setglobal
  92. } if
  93. dup type /stringtype eq {
  94. dup wcheck exch % save attr for setting readonly
  95. .currentglobal true .setglobal
  96. 1 index length string exch .setglobal
  97. copy exch not { readonly } if
  98. } if
  99. } .bind def
  100. % Some user parameters are managed entirely at the PostScript level.
  101. % We take care of that here.
  102. systemdict begin
  103. /psuserparams 48 dict def
  104. /getuserparam { % <name> getuserparam <value>
  105. /userparams .systemvar 1 index get exch pop
  106. } odef
  107. % Fill in userparams (created by the interpreter) with current values.
  108. mark .currentuserparams
  109. counttomark 2 idiv {
  110. userparams 3 1 roll put
  111. } repeat pop
  112. /.definepsuserparam { % <name> <value> .definepsuserparam -
  113. psuserparams 3 copy pop
  114. type cvlit /.checkparamtype cvx 2 packedarray cvx put
  115. userparams 3 1 roll put
  116. } .bind def
  117. end
  118. /currentuserparams { % - currentuserparams <dict>
  119. /userparams .systemvar dup length dict .copydict
  120. } odef
  121. /setuserparams { % <dict> setuserparams -
  122. % Check that we will be able to set the PostScript-level
  123. % user parameters.
  124. /setuserparams /psuserparams .systemvar .checksetparams
  125. % Set the C-level user params. If this succeeds, we know that
  126. % the password check succeeded.
  127. dup .setuserparams
  128. % Now set the PostScript-level params.
  129. % The interpreter may have adjusted the values of some of the
  130. % parameters, so we have to read them back.
  131. dup {
  132. /userparams .systemvar 2 index known {
  133. psuserparams 2 index known not {
  134. pop dup .getuserparam
  135. } if
  136. .copyparam
  137. % special protection for the security related parameters
  138. [ /PermitFileReading /PermitFileWriting /PermitFileControl ]
  139. { 2 index eq { % force all strings to readonly but make sure the
  140. % array is in the correct VM space (local/global).
  141. currentglobal exch dup gcheck setglobal
  142. dup length array exch { readonly exch } forall astore
  143. exch setglobal
  144. } if
  145. } forall
  146. % protect top level of parameters that we copied
  147. dup type dup /arraytype eq exch /stringtype eq or { readonly } if
  148. /userparams .systemvar 3 1 roll .forceput % userparams is read-only
  149. } {
  150. pop pop
  151. } ifelse
  152. } forall
  153. % A context switch might have occurred during the above loop,
  154. % causing the interpreter-level parameters to be reset.
  155. % Set them again to the new values. From here on, we are safe,
  156. % since a context switch will consult userparams.
  157. .setuserparams
  158. } .bind odef
  159. % Initialize user parameters managed here.
  160. /JobName () .definepsuserparam
  161. % Restore must restore the user parameters.
  162. % (Since userparams is in local VM, save takes care of saving them.)
  163. /restore { % <save> restore -
  164. //restore /userparams .systemvar .setuserparams
  165. } .bind odef
  166. % The pssystemparams dictionary holds some system parameters that
  167. % are managed entirely at the PostScript level.
  168. systemdict begin
  169. currentdict /pssystemparams known not {
  170. /pssystemparams 40 dict readonly def
  171. } if
  172. /getsystemparam { % <name> getsystemparam <value>
  173. //pssystemparams 1 index .knownget { exch pop } { .getsystemparam } ifelse
  174. } odef
  175. end
  176. /currentsystemparams { % - currentsystemparams <dict>
  177. mark .currentsystemparams //pssystemparams { } forall .dicttomark
  178. } odef
  179. /setsystemparams { % <dict> setsystemparams -
  180. % Check that we will be able to set the PostScript-level
  181. % system parameters.
  182. /SAFETY .systemvar /safe get {
  183. % SAFER mode disallows some changes
  184. [ /GenericResourceDir /FontResourceDir /GenericResourcePathSep ] {
  185. 2 copy .knownget {
  186. exch //pssystemparams exch .knownget {
  187. ne { /setsystemparams /invalidaccess signalerror } if
  188. } {
  189. pop
  190. } ifelse
  191. } {
  192. pop
  193. } ifelse
  194. } forall
  195. } if
  196. /setsystemparams //pssystemparams mark exch {
  197. type cvlit /.checkparamtype cvx 2 packedarray cvx
  198. } forall .dicttomark .checksetparams
  199. % Set the C-level system params. If this succeeds, we know that
  200. % the password check succeeded.
  201. dup .setsystemparams
  202. % Now set the PostScript-level params. We must copy local strings
  203. % into global VM.
  204. dup
  205. { //pssystemparams 2 index known
  206. { % Stack: key newvalue
  207. .copyparam
  208. % protect top level parameters that we copied
  209. dup type dup /arraytype eq exch /stringtype eq or { readonly } if
  210. //pssystemparams 3 1 roll .forceput % pssystemparams is read-only
  211. }
  212. { pop pop
  213. }
  214. ifelse
  215. }
  216. forall pop
  217. } .bind odef
  218. % Initialize the passwords.
  219. % NOTE: the names StartJobPassword and SystemParamsPassword are known to
  220. % the interpreter, and must be bound to noaccess strings.
  221. % The length of these strings must be max_password (iutil2.h) + 1.
  222. /StartJobPassword 65 string noaccess def
  223. /SystemParamsPassword 65 string noaccess def
  224. % Redefine cache parameter setting to interact properly with userparams.
  225. /setcachelimit {
  226. mark /MaxFontItem 2 index .dicttomark setuserparams pop
  227. } .bind odef
  228. /setcacheparams {
  229. % The MaxFontCache parameter is a system parameter, which we might
  230. % not be able to set. Fortunately, this doesn't matter, because
  231. % system parameters don't have to be synchronized between this code
  232. % and the VM.
  233. counttomark 1 add copy setcacheparams
  234. currentcacheparams % mark size lower upper
  235. 3 -1 roll pop
  236. /MinFontCompress 3 1 roll
  237. /MaxFontItem exch
  238. .dicttomark setuserparams
  239. cleartomark
  240. } .bind odef
  241. % Add bogus user and system parameters to satisfy badly written PostScript
  242. % programs that incorrectly assume the existence of all the parameters
  243. % listed in Appendix C of the Red Book. Note that some of these may become
  244. % real parameters later: code near the end of gs_init.ps takes care of
  245. % removing any such parameters from ps{user,system}params.
  246. % psuserparams
  247. /MaxFormItem 100000 .definepsuserparam
  248. /MaxPatternItem 20000 .definepsuserparam
  249. /MaxScreenItem 48000 .definepsuserparam
  250. /MaxUPathItem 5000 .definepsuserparam
  251. % File Access Permission parameters
  252. .currentglobal true .setglobal
  253. /.checkFilePermitparams {
  254. type /arraytype eq {
  255. currentuserparams /LockFilePermissions get {
  256. 5 { pop } repeat /setuserparams /invalidaccess signalerror
  257. }{
  258. % in addition to validating the value, ensure the value is read/only
  259. dup { readonly exch } forall
  260. .currentglobal exch dup gcheck .setglobal length array exch .setglobal
  261. astore readonly
  262. }
  263. ifelse
  264. } {
  265. 5 { pop } repeat /setuserparams /typecheck signalerror
  266. }
  267. ifelse
  268. true
  269. } .bind def
  270. % Initialize the File Permission access control to wide open
  271. % These will only be accessed via current/set userparams.
  272. % Values are a string containing multiple nul terminated path strings
  273. /PermitFileReading dup [ (*) ] .definepsuserparam
  274. psuserparams exch /.checkFilePermitparams load put
  275. /PermitFileWriting dup [ (*) ] .definepsuserparam
  276. psuserparams exch /.checkFilePermitparams load put
  277. /PermitFileControl dup [ (*) ] .definepsuserparam
  278. psuserparams exch /.checkFilePermitparams load put
  279. .setglobal
  280. pssystemparams begin
  281. /CurDisplayList 0 .forcedef
  282. /CurFormCache 0 .forcedef
  283. /CurOutlineCache 0 .forcedef
  284. /CurPatternCache 0 .forcedef
  285. /CurUPathCache 0 .forcedef
  286. /CurScreenStorage 0 .forcedef
  287. /CurSourceList 0 .forcedef
  288. /DoPrintErrors false .forcedef
  289. /MaxDisplayList 140000 .forcedef
  290. /MaxFormCache 100000 .forcedef
  291. /MaxOutlineCache 65000 .forcedef
  292. /MaxPatternCache 100000 .forcedef
  293. /MaxUPathCache 300000 .forcedef
  294. /MaxScreenStorage 84000 .forcedef
  295. /MaxSourceList 25000 .forcedef
  296. /RamSize 4194304 .forcedef
  297. end
  298. % Define the procedures for handling comment scanning. The names
  299. % %ProcessComment and %ProcessDSCComment are known to the interpreter.
  300. % These procedures take the file and comment string and file as operands.
  301. /.checkprocesscomment {
  302. dup null eq {
  303. pop true
  304. } {
  305. dup xcheck {
  306. type dup /arraytype eq exch /packedarraytype eq or
  307. } {
  308. pop false
  309. } ifelse
  310. } ifelse
  311. } .bind def
  312. /ProcessComment null .definepsuserparam
  313. psuserparams /ProcessComment {.checkprocesscomment} put
  314. (%ProcessComment) cvn {
  315. /ProcessComment getuserparam
  316. dup null eq { pop pop pop } { exec } ifelse
  317. } bind def
  318. /ProcessDSCComment null .definepsuserparam
  319. psuserparams /ProcessDSCComment {.checkprocesscomment} put
  320. /.loadingfont false def
  321. (%ProcessDSCComment) cvn {
  322. /ProcessDSCComment getuserparam
  323. dup null eq .loadingfont or { pop pop pop } { exec } ifelse
  324. } bind def
  325. % ------ Miscellaneous ------ %
  326. (<<) cvn % - << -mark-
  327. /mark load def
  328. (>>) cvn % -mark- <key1> <value1> ... >> <dict>
  329. /.dicttomark load def
  330. /languagelevel 2 def
  331. % When running in Level 2 mode, this interpreter is supposed to be
  332. % compatible with Adobe version 2017.
  333. /version (2017) readonly def
  334. % If binary tokens are supported by this interpreter,
  335. % set an appropriate default binary object format.
  336. /setobjectformat where
  337. { pop
  338. /RealFormat getsystemparam (IEEE) eq { 1 } { 3 } ifelse
  339. /ByteOrder getsystemparam { 1 add } if
  340. setobjectformat
  341. } if
  342. % Aldus Freehand versions 2.x check for the presence of the
  343. % setcolor operator, and if it is missing, substitute a procedure.
  344. % Unfortunately, the procedure takes different parameters from
  345. % the operator. As a result, files produced by this application
  346. % cause an error if the setcolor operator is actually defined
  347. % and 'bind' is ever used. Aldus fixed this bug in Freehand 3.0,
  348. % but there are a lot of files created by the older versions
  349. % still floating around. Therefore, at Adobe's suggestion,
  350. % we implement the following dreadful hack in the 'where' operator:
  351. % If the key is /setcolor, and
  352. % there is a dictionary named FreeHandDict, and
  353. % currentdict is that dictionary,
  354. % then "where" consults only that dictionary and not any other
  355. % dictionaries on the dictionary stack.
  356. .wheredict /setcolor {
  357. /FreeHandDict .where {
  358. /FreeHandDict get currentdict eq {
  359. pop currentdict /setcolor known { currentdict true } { false } ifelse
  360. } {
  361. .where
  362. } ifelse
  363. } {
  364. .where
  365. } ifelse
  366. } bind put
  367. % ------ Virtual memory ------ %
  368. /currentglobal % - currentglobal <bool>
  369. /currentshared load def
  370. /gcheck % <obj> gcheck <bool>
  371. /scheck load def
  372. /setglobal % <bool> setglobal -
  373. /setshared load def
  374. % We can make the global dictionaries very small, because they auto-expand.
  375. /globaldict currentdict /shareddict .knownget not { 4 dict } if def
  376. /GlobalFontDirectory SharedFontDirectory def
  377. % VMReclaim and VMThreshold are user parameters.
  378. /setvmthreshold { % <int> setvmthreshold -
  379. mark /VMThreshold 2 index .dicttomark setuserparams pop
  380. } odef
  381. /vmreclaim { % <int> vmreclaim -
  382. dup 0 gt {
  383. .vmreclaim
  384. } {
  385. mark /VMReclaim 2 index .dicttomark setuserparams pop
  386. } ifelse
  387. } odef
  388. -1 setvmthreshold
  389. % ------ IODevices ------ %
  390. /.getdevparams where {
  391. pop /currentdevparams { % <iodevice> currentdevparams <dict>
  392. .getdevparams .dicttomark
  393. } odef
  394. } if
  395. /.putdevparams where {
  396. pop /setdevparams { % <iodevice> <dict> setdevparams -
  397. mark 1 index { } forall counttomark 2 add index
  398. .putdevparams pop pop
  399. } odef
  400. } if
  401. % ------ Job control ------ %
  402. serverdict begin
  403. % We could protect the job information better, but we aren't attempting
  404. % (currently) to protect ourselves against maliciousness.
  405. /.jobsave null def % top-level save object
  406. /.jobsavelevel 0 def % save depth of job (0 if .jobsave is null,
  407. % 1 otherwise)
  408. /.adminjob true def % status of current unencapsulated job
  409. end % serverdict
  410. % Because there may be objects on the e-stack created since the job save,
  411. % we have to clear the e-stack before doing the end-of-job restore.
  412. % We do this by executing a 2 .stop, which is caught by the 2 .stopped
  413. % in .runexec; we leave on the o-stack a procedure to execute aftewards.
  414. %
  415. %**************** The definition of startjob is not complete yet, since
  416. % it doesn't reset stdin/stdout.
  417. /.startnewjob { % <exit_bool> <password_level>
  418. % .startnewjob -
  419. serverdict /.jobsave get dup null eq { pop } { restore } ifelse
  420. exch {
  421. % Unencapsulated job
  422. serverdict /.jobsave null put
  423. serverdict /.jobsavelevel 0 put
  424. serverdict /.adminjob 3 -1 roll 1 gt put
  425. % The Adobe documentation doesn't say what happens to the
  426. % graphics state stack in this case, but an experiment
  427. % produced results suggesting that a grestoreall occurs.
  428. grestoreall
  429. } {
  430. % Encapsulated job
  431. pop
  432. serverdict /.jobsave save put
  433. serverdict /.jobsavelevel 1 put
  434. .userdict /quit /stop load put
  435. } ifelse
  436. % Reset the interpreter state.
  437. clear cleardictstack
  438. initgraphics
  439. false setglobal
  440. 2 vmreclaim % Make sure GC'ed memory is reclaimed and freed.
  441. } bind def
  442. /.startjob { % <exit_bool> <password> <finish_proc>
  443. % .startjob <ok_bool>
  444. vmstatus pop pop serverdict /.jobsavelevel get eq
  445. 2 index .checkpassword 0 gt and {
  446. exch .checkpassword exch count 3 roll count 3 sub { pop } repeat
  447. cleardictstack
  448. % Reset the e-stack back to the 2 .stopped in .runexec,
  449. % passing the finish_proc to be executed afterwards.
  450. 2 .stop
  451. } { % Password check failed
  452. pop pop pop false
  453. } ifelse
  454. } odef
  455. /startjob { % <exit_bool> <password> startjob <ok_bool>
  456. % This is a hack. We really need some way to indicate explicitly
  457. % to the interpreter that we are under control of a job server.
  458. { .startnewjob true } .startjob
  459. } odef
  460. % The procedure to undo the job encapsulation
  461. /.endjob {
  462. clear cleardictstack
  463. serverdict /.jobsave get dup null eq { pop } { restore } ifelse
  464. serverdict /.jobsave null put
  465. 2 vmreclaim % recover local and global VM
  466. } odef
  467. systemdict begin
  468. /quit { % - quit -
  469. //systemdict begin serverdict /.jobsave get null eq
  470. { end //quit }
  471. { /quit load /invalidaccess /signalerror load end exec }
  472. ifelse
  473. } bind odef
  474. end
  475. % We would like to define exitserver as a procedure, using the code
  476. % that the Red Book says is equivalent to it. However, since startjob
  477. % resets the exec stack, we can't do this, because control would never
  478. % proceed past the call on startjob if the exitserver is successful.
  479. % Instead, we need to construct exitserver out of pieces of startjob.
  480. serverdict begin
  481. /exitserver { % <password> exitserver -
  482. true exch { .startnewjob } .startjob not {
  483. /exitserver /invalidaccess signalerror
  484. } if
  485. } bind def
  486. end % serverdict
  487. % ------ Compatibility ------ %
  488. % In Level 2 mode, the following replace the definitions that gs_statd.ps
  489. % installs in statusdict and serverdict.
  490. % Note that statusdict must be allocated in local VM.
  491. % We don't bother with many of these yet.
  492. /.dict1 { exch mark 3 1 roll .dicttomark } bind def
  493. currentglobal false setglobal 25 dict exch setglobal begin
  494. currentsystemparams
  495. % The following do not depend on the presence of setpagedevice.
  496. /buildtime 1 index /BuildTime get def
  497. % Also define /buildtime in systemdict because Adobe does so and some fonts use it as ID
  498. systemdict /buildtime dup load put
  499. /byteorder 1 index /ByteOrder get def
  500. /checkpassword { .checkpassword 0 gt } bind def
  501. dup /DoStartPage known
  502. { /dostartpage { /DoStartPage getsystemparam } bind def
  503. /setdostartpage { /DoStartPage .dict1 setsystemparams } bind def
  504. } if
  505. dup /StartupMode known
  506. { /dosysstart { /StartupMode getsystemparam 0 ne } bind def
  507. /setdosysstart { { 1 } { 0 } ifelse /StartupMode .dict1 setsystemparams } bind def
  508. } if
  509. %****** Setting jobname is supposed to set userparams.JobName, too.
  510. /jobname { /JobName getuserparam } bind def
  511. /jobtimeout { /JobTimeout getuserparam } bind def
  512. /ramsize { /RamSize getsystemparam } bind def
  513. /realformat 1 index /RealFormat get def
  514. dup /PrinterName known
  515. { /setprintername { /PrinterName .dict1 setsystemparams } bind def
  516. } if
  517. /printername
  518. { currentsystemparams /PrinterName .knownget not { () } if exch copy
  519. } bind def
  520. currentuserparams /WaitTimeout known
  521. { /waittimeout { /WaitTimeout getuserparam } bind def
  522. } if
  523. % The following do require setpagedevice.
  524. /.setpagedevice where { pop } { (%END PAGEDEVICE) .skipeof } ifelse
  525. /defaulttimeouts
  526. { currentsystemparams dup
  527. /JobTimeout .knownget not { 0 } if
  528. exch /WaitTimeout .knownget not { 0 } if
  529. currentpagedevice /ManualFeedTimeout .knownget not { 0 } if
  530. } bind def
  531. /margins
  532. { currentpagedevice /Margins .knownget { exch } { [0 0] } ifelse
  533. } bind def
  534. /pagemargin
  535. { currentpagedevice /PageOffset .knownget { 0 get } { 0 } ifelse
  536. } bind def
  537. /pageparams
  538. { currentpagedevice
  539. dup /Orientation .knownget { 1 and ORIENT1 { 1 xor } if } { 0 } ifelse exch
  540. dup /PageSize get aload pop 3 index 0 ne { exch } if 3 2 roll
  541. /PageOffset .knownget { 0 get } { 0 } ifelse 4 -1 roll
  542. } bind def
  543. /setdefaulttimeouts
  544. { exch mark /ManualFeedTimeout 3 -1 roll
  545. /Policies mark /ManualFeedTimeout 1 .dicttomark
  546. .dicttomark setpagedevice
  547. /WaitTimeout exch mark /JobTimeout 5 2 roll .dicttomark setsystemparams
  548. } bind def
  549. /.setpagesize { 2 array astore /PageSize .dict1 setpagedevice } bind def
  550. /setduplexmode { /Duplex .dict1 setpagedevice } bind def
  551. /setmargins
  552. { exch 2 array astore /Margins .dict1 setpagedevice
  553. } bind def
  554. /setpagemargin { 0 2 array astore /PageOffset .dict1 setpagedevice } bind def
  555. /setpageparams
  556. { mark /PageSize 6 -2 roll
  557. 4 index 1 and ORIENT1 { 1 } { 0 } ifelse ne { exch } if 2 array astore
  558. /Orientation 5 -1 roll ORIENT1 { 1 xor } if
  559. /PageOffset counttomark 2 add -1 roll 0 2 array astore
  560. .dicttomark setpagedevice
  561. } bind def
  562. /setresolution
  563. { dup 2 array astore /HWResolution .dict1 setpagedevice
  564. } bind def
  565. %END PAGEDEVICE
  566. % The following are not implemented yet.
  567. %manualfeed
  568. %manualfeedtimeout
  569. %pagecount
  570. %pagestackorder
  571. %setpagestackorder
  572. pop % currentsystemparams
  573. % Flag the current dictionary so it will be swapped when we
  574. % change language levels. (See zmisc2.c for more information.)
  575. /statusdict currentdict def
  576. currentdict end
  577. /statusdict exch .forcedef % statusdict is local, systemdict is global
  578. % The following compatibility operators are in systemdict. They are
  579. % defined here, rather than in gs_init.ps, because they require the
  580. % resource machinery.
  581. /devforall { % <proc> <scratch> devforall -
  582. exch {
  583. 1 index currentdevparams
  584. /Type .knownget { /FileSystem eq } { false } ifelse
  585. { exec } { pop pop } ifelse
  586. } /exec load 3 packedarray cvx exch
  587. (*) 3 1 roll /IODevice resourceforall
  588. } odef
  589. /devstatus { % <(%disk*%)> devstatus <searchable> <writable>
  590. % <hasNames> <mounted> <removable> <searchOrder>
  591. % <freePages> <size> true
  592. % <string> devstatus false
  593. dup length 5 ge {
  594. dup 0 5 getinterval (%disk) eq {
  595. dup /IODevice resourcestatus {
  596. pop pop dup currentdevparams
  597. dup /Searchable get
  598. exch dup /Writeable get
  599. exch dup /HasNames get
  600. exch dup /Mounted get
  601. exch dup /Removable get
  602. exch dup /SearchOrder get
  603. exch dup /Free get
  604. exch /LogicalSize get
  605. 9 -1 roll pop true
  606. } {
  607. pop false
  608. } ifelse
  609. } {
  610. pop false
  611. } ifelse
  612. } {
  613. pop false
  614. } ifelse
  615. } odef
  616. % ------ Color spaces ------ %
  617. % Move setcolorsapce, setcolor, and colorspacedict to level2dict
  618. level2dict /setcolorspace .cspace_util 1 index get put
  619. level2dict /setcolor .cspace_util 1 index get put
  620. level2dict /colorspacedict .cspace_util 1 index get put
  621. % Add the level 2 color spaces
  622. % DevicePixel is actually a LanguageLevel 3 feature; it is here for
  623. % historical reasons.
  624. %% Replace 1 (gs_devpxl.ps)
  625. (gs_devpxl.ps) runlibfile
  626. %% Replace 1 (gs_ciecs2.ps)
  627. (gs_ciecs2.ps) runlibfile
  628. %% Replace 1 (gs_indxd.ps)
  629. (gs_indxd.ps) runlibfile
  630. %% Replace 1 (gs_sepr.ps)
  631. (gs_sepr.ps) runlibfile
  632. %% Replace 1 (gs_patrn.ps)
  633. (gs_patrn.ps) runlibfile
  634. % ------ CIE color rendering ------ %
  635. % Define findcolorrendering and a default ColorRendering ProcSet.
  636. /findcolorrendering { % <intentname> findcolorrendering
  637. % <crdname> <found>
  638. /ColorRendering /ProcSet findresource
  639. 1 index .namestring (.) concatstrings
  640. 1 index /GetPageDeviceName get exec .namestring (.) concatstrings
  641. 2 index /GetHalftoneName get exec .namestring
  642. concatstrings concatstrings
  643. dup /ColorRendering resourcestatus {
  644. pop pop exch pop exch pop true
  645. } {
  646. pop /GetSubstituteCRD get exec false
  647. } ifelse
  648. } odef
  649. 5 dict dup begin
  650. /GetPageDeviceName { % - GetPageDeviceName <name>
  651. currentpagedevice dup /PageDeviceName .knownget {
  652. exch pop dup null eq { pop /none } if
  653. } {
  654. pop /none
  655. } ifelse
  656. } bind def
  657. /GetHalftoneName { % - GetHalftoneName <name>
  658. currenthalftone /HalftoneName .knownget not { /none } if
  659. } bind def
  660. /GetSubstituteCRD { % <intentname> GetSubstituteCRD <crdname>
  661. pop /DefaultColorRendering
  662. } bind def
  663. end
  664. % The resource machinery hasn't been activated, so just save the ProcSet
  665. % and let .fixresources finish the installation process.
  666. /ColorRendering exch def
  667. % Define setcolorrendering.
  668. /.colorrenderingtypes 5 dict def
  669. /setcolorrendering { % <crd> setcolorrendering -
  670. dup /ColorRenderingType get //.colorrenderingtypes exch get exec
  671. } odef
  672. /.setcolorrendering1 where { pop } { (%END CRD) .skipeof } ifelse
  673. .colorrenderingtypes 1 {
  674. dup .buildcolorrendering1 .setcolorrendering1
  675. } .bind put
  676. % Note: the value 101 in the next line must be the same as the value of
  677. % GX_DEVICE_CRD1_TYPE in gscrdp.h.
  678. .colorrenderingtypes 101 {
  679. dup .builddevicecolorrendering1 .setdevicecolorrendering1
  680. } .bind put
  681. % sRGB output CRD, D65 white point
  682. mark
  683. /ColorRenderingType 1
  684. /RangePQR [ -0.5 2 -0.5 2 -0.5 2 ] readonly
  685. % Bradford Cone Space
  686. /MatrixPQR [ 0.8951 -0.7502 0.0389
  687. 0.2664 1.7135 -0.0685
  688. -0.1614 0.0367 1.0296] readonly
  689. /MatrixLMN [ 3.240449 -0.969265 0.055643
  690. -1.537136 1.876011 -0.204026
  691. -0.498531 0.041556 1.057229 ] readonly
  692. % Inverse sRGB gamma transform
  693. /EncodeABC [ { dup 0.00304 le
  694. { 12.92321 mul }
  695. { 1 2.4 div exp 1.055 mul 0.055 sub }
  696. ifelse
  697. } bind dup dup
  698. ] readonly
  699. /WhitePoint [ 0.9505 1 1.0890 ] readonly % D65
  700. /BlackPoint [ 0 0 0 ] readonly
  701. % VonKries-like transform in Bradford Cone Space
  702. /TransformPQR
  703. % The implementations have been moved to C for performance.
  704. [ { .TransformPQR_scale_WB0 } bind
  705. { .TransformPQR_scale_WB1 } bind
  706. { .TransformPQR_scale_WB2 } bind
  707. ] readonly
  708. .dicttomark setcolorrendering
  709. %END CRD
  710. % Initialize a CIEBased color space for sRGB.
  711. /CIEsRGB [ /CIEBasedABC
  712. mark
  713. /DecodeLMN [ {
  714. dup 0.03928 le { 12.92321 div } { 0.055 add 1.055 div 2.4 exp } ifelse
  715. } bind dup dup ] readonly
  716. /MatrixLMN [
  717. 0.412457 0.212673 0.019334
  718. 0.357576 0.715152 0.119192
  719. 0.180437 0.072175 0.950301
  720. ] readonly
  721. /WhitePoint [0.9505 1.0 1.0890] readonly
  722. .dicttomark readonly
  723. ] readonly def
  724. % ------ Painting ------ %
  725. % A straightforward definition of execform that doesn't actually
  726. % do any caching.
  727. /.execform1 {
  728. % This is a separate operator so that the stacks will be restored
  729. % properly if an error occurs.
  730. dup /Matrix get concat
  731. dup /BBox get aload pop
  732. exch 3 index sub exch 2 index sub rectclip
  733. dup /PaintProc get
  734. 1 index /Implementation known not {
  735. 1 index dup /Implementation null .forceput readonly pop
  736. } if
  737. exec
  738. } .bind odef % must bind .forceput
  739. /.formtypes 5 dict
  740. dup 1 /.execform1 load put
  741. def
  742. /execform { % <form> execform -
  743. gsave {
  744. dup /FormType get //.formtypes exch get exec
  745. } stopped grestore { stop } if
  746. } odef
  747. /.patterntypes 5 dict
  748. dup 1 /.buildpattern1 load put
  749. def
  750. /makepattern { % <proto_dict> <matrix> makepattern <pattern>
  751. //.patterntypes 2 index /PatternType get get
  752. .currentglobal false .setglobal exch
  753. % Stack: proto matrix global buildproc
  754. 3 index dup length 1 add dict .copydict
  755. 3 index 3 -1 roll exec 3 -1 roll .setglobal
  756. 1 index /Implementation 3 -1 roll put
  757. readonly exch pop exch pop
  758. } odef
  759. /setpattern { % [<comp1> ...] <pattern> setpattern -
  760. currentcolorspace 0 get /Pattern ne {
  761. [ /Pattern currentcolorspace ] setcolorspace
  762. } if setcolor
  763. } odef
  764. % The following functions emulate the actions of findcmykcustomcolor and
  765. % setcustomcolor. These functions are described in Adobe's TN 5044. That
  766. % same document also says "The following “operators” are not defined in the
  767. % PostScript Language Reference Manual, but should be used as pseudo-operators
  768. % in your PostScript language output. Separation applications from Adobe
  769. % Systems and other vendors will redefine these convention operators to
  770. % separate your documents. Your application should conditionally define
  771. % procedures with these special names, as shown later in this document."
  772. %
  773. % We are providing these functions because we have found files created by
  774. % "QuarkXPress: pictwpstops filter 1.0" which produce bad shading dictionaries
  775. % if these operators are not defined.
  776. % Conditionally disable the TN 5044 psuedo-ops if NO_TN5044 specified
  777. /NO_TN5044 where { pop (%END TN 5044 psuedo-ops) .skipeof } if
  778. % TN 5044 does not define the contents of the array. We are simply putting
  779. % the values given into an array. This is consistent with what we see when
  780. % testing with Adobe Distiller 6.0.
  781. % <cyan> <magenta> <yellow> <black> <key> findcmykcustomcolor <array>
  782. /findcmykcustomcolor { 5 array astore } bind def
  783. % Build a tint transform function for use by setcustomcolor. This function
  784. % is for a Separation color space which has a DeviceCMYK base color space
  785. % (i.e. 1 input and 4 outputs). The input to buildcustomtinttransform is the
  786. % array created by findcmykcustomcolor. The resulting function is:
  787. % { dup cyan mul exch dup magenta mul exch dup yellow mul exch black mul }
  788. % Where cyan, magenta, yellow, and black are values from the array.
  789. /buildcustomtinttransform % <array> buildcustomtinttransform <function>
  790. { [ /dup load 2 index 0 get /mul load
  791. /exch load /dup load 6 index 1 get /mul load
  792. /exch load /dup load 10 index 2 get /mul load
  793. /exch load 13 index 3 get /mul load
  794. ] cvx bind
  795. exch pop % Remove the input array
  796. } bind def
  797. % Set a custom color based upon a tint and array which describes the custom
  798. % color. See findcmykcustomcolor. First we create and then set a Separation
  799. % colorspace. Then we set the specified color.
  800. % Note that older Adobe ProcSets apparently allow for 'null' as the tint
  801. % for some reason, so an alternate operational mode is tolerated:
  802. % null setcustomcolor -
  803. /setcustomcolor % <array> <tint> setcustomcolor -
  804. { dup //null ne {
  805. % Start building Separation colorspace
  806. [ /Separation 3 index 4 get % Get separation name from array's key
  807. /DeviceCMYK
  808. 5 index buildcustomtinttransform ] % build the tint transform function
  809. setcolorspace % Set the Separation color space as current
  810. setcolor % Set the tint as the current color
  811. pop % Remove the input array
  812. }
  813. { pop } % 'null' as the tint is ignored
  814. ifelse
  815. } bind def
  816. % This proc is supposed to implement a version of overprinting. TN 5044 says
  817. % that this proc is not used by any shipping host-based application. We have
  818. % only found it being used in a proc set in files by Canvas from Deneba Systems.
  819. % Even their proc set does not actually do any overprinting. However their
  820. % files crash if this is not defined. Thus we have a copy of this proc but
  821. % we are simply checking for inputs being -1 and if so then we set the value
  822. % to 0.
  823. /setcmykoverprint {
  824. 4 { dup -1 eq { pop 0 } if 4 1 roll } repeat setcmykcolor
  825. } bind def
  826. %END TN 5044 psuedo-ops
  827. end % level2dict