1
0

gs_lev2.ps 31 KB

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