gs_res.ps 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929
  1. % Copyright (C) 1994, 1996, 1997, 1998, 1999, 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_res.ps,v 1.16 2001/10/01 05:56:58 lpd Exp $
  18. % Initialization file for Level 2 resource machinery.
  19. % When this is run, systemdict is still writable,
  20. % but (almost) everything defined here goes into level2dict.
  21. level2dict begin
  22. (BEGIN RESOURCES) VMDEBUG
  23. % We keep track of (global) instances with another entry in the resource
  24. % dictionary, an .Instances dictionary. For categories with implicit
  25. % instances, the values in .Instances are the same as the keys;
  26. % for other categories, the values are [instance status size].
  27. % Note that the dictionary that defines a resource category is stored
  28. % in global VM. The PostScript manual says that each category must
  29. % manage global and local instances separately. However, objects in
  30. % global VM other than systemdict can't reference objects in local VM.
  31. % This means that the resource category dictionary, which would otherwise be
  32. % the obvious place to keep track of the instances, can't be used to keep
  33. % track of local instances. Instead, we define a dictionary in local VM
  34. % called localinstancedict, in which the key is the category name and
  35. % the value is the analogue of .Instances for local instances.
  36. % We don't currently implement automatic resource unloading.
  37. % When and if we do, it should be hooked to the garbage collector.
  38. % However, Ed Taft of Adobe says their interpreters don't implement this
  39. % either, so we aren't going to worry about it for a while.
  40. currentglobal false setglobal systemdict begin
  41. /localinstancedict 5 dict
  42. .forcedef % localinstancedict is local, systemdict is global
  43. end true setglobal
  44. /.emptydict 0 dict readonly def
  45. setglobal
  46. % Resource category dictionaries have the following keys (those marked with
  47. % * are optional):
  48. % Standard, defined in the Red Book:
  49. % Category (name)
  50. % *InstanceType (name)
  51. % DefineResource
  52. % <key> <instance> DefineResource <instance>
  53. % UndefineResource
  54. % <key> UndefineResource -
  55. % FindResource
  56. % <key> FindResource <instance>
  57. % ResourceStatus
  58. % <key> ResourceStatus <status> <size> true
  59. % <key> ResourceStatus false
  60. % ResourceForAll
  61. % <template> <proc> <scratch> ResourceForAll -
  62. % *ResourceFileName
  63. % <key> <scratch> ResourceFileName <filename>
  64. % Additional, specific to our implementation:
  65. % .Instances (dictionary)
  66. % .LocalInstances
  67. % - .LocalInstances <dict>
  68. % .GetInstance
  69. % <key> .GetInstance <instance> -true-
  70. % <key> .GetInstance -false-
  71. % .CheckResource
  72. % <key> <value> .CheckResource <key> <value> <ok>
  73. % (or may give an error if not OK)
  74. % .DoLoadResource
  75. % <key> .DoLoadResource <key> (may give an error)
  76. % .LoadResource
  77. % <key> .LoadResource - (may give an error)
  78. % .ResourceFile
  79. % <key> .ResourceFile <file> -true-
  80. % <key> .ResourceFile <key> -false-
  81. % .ResourceFileStatus
  82. % <key> .ResourceFileStatus 2 <vmusage> -true-
  83. % <key> .ResourceFileStatus -false-
  84. % All the above procedures expect that the top dictionary on the d-stack
  85. % is the resource dictionary.
  86. % Define enough of the Category category so we can define other categories.
  87. % The dictionary we're about to create will become the Category
  88. % category definition dictionary.
  89. % .findcategory and .resourceexec are only called from within the
  90. % implementation of the resource 'operators', so they doesn't have to worry
  91. % about cleaning up the stack if they fail (the interpreter's stack
  92. % protection machinery for pseudo-operators takes care of this).
  93. /.findcategory { % <name> .findcategory -
  94. % (pushes the category on the dstack)
  95. /Category findresource begin
  96. } bind def
  97. /.resourceexec { % <key> /xxxResource .resourceexec -
  98. % (also pops the category from the dstack)
  99. load exec end
  100. } bind def
  101. % .getvminstance treats instances on disk as undefined.
  102. /.getvminstance { % <key> .getvminstance <instance> -true-
  103. % <key> .getvminstance -false-
  104. .GetInstance {
  105. dup 1 get 2 ne { true } { pop false } ifelse
  106. } {
  107. false
  108. } ifelse
  109. } bind def
  110. 20 dict begin
  111. % Standard entries
  112. /Category /Category def
  113. /InstanceType /dicttype def
  114. /DefineResource {
  115. .CheckResource {
  116. dup /Category 3 index cvlit .growput
  117. dup [ exch 0 -1 ] exch
  118. .Instances 4 2 roll put
  119. % Make the Category dictionary read-only. We will have to
  120. % use .forceput / .forcedef later to replace the dummy,
  121. % empty .Instances dictionary with the real one later.
  122. readonly
  123. } {
  124. /defineresource load /typecheck signalerror
  125. } ifelse
  126. } bind def
  127. /FindResource % (redefined below)
  128. { .Instances exch get 0 get
  129. } bind def
  130. % Additional entries
  131. /.Instances 30 dict def
  132. .Instances /Category [currentdict 0 -1] put
  133. /.LocalInstances 0 dict def
  134. /.GetInstance
  135. { .Instances exch .knownget
  136. } bind def
  137. /.CheckResource
  138. { dup gcheck currentglobal and
  139. { /DefineResource /FindResource /ResourceForAll /ResourceStatus
  140. /UndefineResource }
  141. { 2 index exch known and }
  142. forall
  143. not { /defineresource load /invalidaccess signalerror } if
  144. true
  145. } bind def
  146. .Instances end begin % for the base case of findresource
  147. (END CATEGORY) VMDEBUG
  148. % Define the resource operators. We use the "stack protection" feature of
  149. % odef to make sure the stacks are restored properly on an error.
  150. % This requires that the operators not pop anything from the stack until
  151. % they have executed their logic successfully. We can't make this
  152. % work for resourceforall, because the procedure it executes mustn't see
  153. % the operands of resourceforall on the stack, but we can make it work for
  154. % the others.
  155. % findresource is the only operator that needs to bind //Category.
  156. /findresource { % <key> <category> findresource <instance>
  157. 2 copy dup /Category eq
  158. { pop //Category 0 get begin } { .findcategory } ifelse
  159. /FindResource .resourceexec exch pop exch pop
  160. } bind
  161. end % .Instances of Category
  162. odef
  163. /defineresource { % <key> <instance> <category> defineresource <instance>
  164. 3 copy .findcategory
  165. currentdict /InstanceType known {
  166. dup type InstanceType ne {
  167. dup type /packedarraytype eq InstanceType /arraytype eq and
  168. not { /defineresource load /typecheck signalerror } if
  169. } if
  170. } if
  171. /DefineResource .resourceexec
  172. 4 1 roll pop pop pop
  173. } bind odef
  174. % We must prevent resourceforall from automatically restoring the stacks,
  175. % because we don't want the stacks restored if proc causes an error.
  176. % On the other hand, resourceforall is defined in the PLRM as an operator,
  177. % so it must have type /operatortype. We hack this by taking advantage of
  178. % the fact that the interpreter optimizes tail calls, so stack protection
  179. % doesn't apply to the very last token of an operator procedure.
  180. /resourceforall1 { % <template> <proc> <scratch> <category> resourceforall1 -
  181. dup /Category findresource begin
  182. /ResourceForAll load
  183. % Make sure we can recover the original operands.
  184. % We must create the array in local VM, in case any of the
  185. % operands are local.
  186. % Stack: ...operands... proc
  187. 5 copy pop .currentglobal false .setglobal 5 1 roll
  188. 4 packedarray exch .setglobal count
  189. % Stack: ...operands... proc saved count
  190. 4 -1 roll pop % pop the category
  191. /stopped load 3 1 roll
  192. 3 .execn
  193. % Stack: ... stopped saved count
  194. 3 -1 roll {
  195. .currentstackprotect {
  196. % The count is the original stack depth + 2.
  197. count exch 4 sub sub { exch pop } repeat
  198. aload pop end
  199. } {
  200. % Don't restore the stacks.
  201. pop pop
  202. } ifelse stop
  203. } {
  204. pop pop end
  205. } ifelse
  206. } bind def
  207. /resourceforall { % <template> <proc> <scratch> <category> resourceforall1 -
  208. //resourceforall1 exec % see above
  209. } bind odef
  210. /resourcestatus { % <key> <category> resourcestatus <status> <size> true
  211. % <key> <category> resourcestatus false
  212. 2 copy .findcategory /ResourceStatus .resourceexec
  213. { 4 2 roll pop pop true } { pop pop false } ifelse
  214. } bind odef
  215. /undefineresource { % <key> <category> undefineresource -
  216. 2 copy .findcategory /UndefineResource .resourceexec pop pop
  217. } bind odef
  218. % Define the system parameters used for the Generic implementation of
  219. % ResourceFileName.
  220. systemdict begin
  221. currentdict /pssystemparams known not {
  222. /pssystemparams 10 dict readonly def
  223. } if
  224. pssystemparams begin
  225. /FontResourceDir (/Resource/Font/) readonly .forcedef % pssys'params is r-o
  226. /GenericResourceDir (/Resource/) readonly .forcedef % pssys'params is r-o
  227. /GenericResourcePathSep (/) readonly .forcedef % pssys'params is r-o
  228. end
  229. end
  230. % Define the generic algorithm for computing resource file names.
  231. /.rfnstring 100 string def
  232. /.genericrfn % <key> <scratch> <prefix> .genericrfn <filename>
  233. { 3 -1 roll //.rfnstring cvs concatstrings exch copy
  234. } bind def
  235. % Define a procedure for making a packed array in local VM.
  236. /.localpackedarray { % <obj1> ... <objn> <n> .localpackedarray <packedarray>
  237. .currentglobal false .setglobal 1 index 2 add 1 roll
  238. packedarray exch .setglobal
  239. } bind def
  240. % Define the Generic category.
  241. /Generic mark
  242. % Standard entries
  243. % We're still running in Level 1 mode, so dictionaries won't expand.
  244. % Leave room for the /Category entry.
  245. /Category null
  246. % Implement the body of Generic resourceforall for local, global, and
  247. % external cases. 'args' is [template proc scratch resdict].
  248. /.enumerateresource { % <key> [- <proc> <scratch>] .enumerateresource -
  249. 1 index type dup /stringtype eq exch /nametype eq or {
  250. exch 1 index 2 get cvs exch
  251. } if
  252. % Use .setstackprotect to prevent the stacks from being restored if
  253. % an error occurs during execution of proc.
  254. 1 get false .setstackprotect exec true .setstackprotect
  255. } bind def
  256. /.localresourceforall { % <key> <value> <args> .localr'forall -
  257. exch pop
  258. 2 copy 0 get .stringmatch { .enumerateresource } { pop pop } ifelse
  259. } bind def
  260. /.globalresourceforall { % <key> <value> <args> .globalr'forall -
  261. exch pop
  262. 2 copy 0 get .stringmatch {
  263. dup 3 get begin .LocalInstances end 2 index known not {
  264. .enumerateresource
  265. } if
  266. } {
  267. pop pop
  268. } ifelse
  269. } bind def
  270. /.externalresourceforall { % <filename> <len> <args> .externalr'forall -
  271. 3 1 roll 1 index length 1 index sub getinterval exch
  272. dup 3 get begin .Instances .LocalInstances end
  273. % Stack: key args insts localinsts
  274. 3 index known {
  275. pop pop pop
  276. } {
  277. 2 index known { pop pop } { .enumerateresource } ifelse
  278. } ifelse
  279. } bind def
  280. /DefineResource {
  281. .CheckResource
  282. { dup [ exch 0 -1 ]
  283. % Stack: key value instance
  284. currentglobal
  285. { false setglobal 2 index UndefineResource % remove local def if any
  286. true setglobal
  287. .Instances dup //.emptydict eq {
  288. pop 3 dict
  289. % As noted above, Category dictionaries are read-only,
  290. % so we have to use .forcedef here.
  291. /.Instances 1 index .forcedef % Category dict is read-only
  292. } if
  293. }
  294. { .LocalInstances dup //.emptydict eq
  295. { pop 3 dict localinstancedict Category 2 index put
  296. }
  297. if
  298. }
  299. ifelse
  300. % Stack: key value instance instancedict
  301. 3 index 2 index .growput
  302. % Now make the resource value read-only.
  303. 0 2 copy get { readonly } .internalstopped pop
  304. dup 4 1 roll put exch pop exch pop
  305. }
  306. { /defineresource load /typecheck signalerror
  307. }
  308. ifelse
  309. } bind executeonly % executeonly to prevent access to .forcedef
  310. /UndefineResource
  311. { { dup 2 index .knownget
  312. { dup 1 get 1 ge
  313. { dup 0 null put 1 2 put pop pop }
  314. { pop exch .undef }
  315. ifelse
  316. }
  317. { pop pop
  318. }
  319. ifelse
  320. }
  321. currentglobal
  322. { 2 copy .Instances exch exec
  323. }
  324. if .LocalInstances exch exec
  325. } bind
  326. % Because of some badly designed code in Adobe's CID font downloader that
  327. % makes findresource and resourcestatus deliberately inconsistent with each
  328. % other, the default FindResource must not call ResourceStatus if there is
  329. % an instance of the desired name already defined in VM.
  330. /FindResource {
  331. dup .getvminstance {
  332. exch pop 0 get
  333. } {
  334. dup ResourceStatus {
  335. pop 1 gt {
  336. .DoLoadResource .getvminstance not {
  337. /findresource load /undefinedresource signalerror
  338. } if 0 get
  339. } {
  340. .GetInstance pop 0 get
  341. } ifelse
  342. } {
  343. /findresource load /undefinedresource signalerror
  344. } ifelse
  345. } ifelse
  346. } bind
  347. % Because of some badly designed code in Adobe's CID font downloader, the
  348. % definition of ResourceStatus for Generic and Font must be the same (!).
  349. % We patch around this by using an intermediate .ResourceFileStatus procedure.
  350. /ResourceStatus {
  351. dup .GetInstance {
  352. exch pop dup 1 get exch 2 get true
  353. } {
  354. .ResourceFileStatus
  355. } ifelse
  356. } bind
  357. /.ResourceFileStatus {
  358. .ResourceFile { closefile 2 -1 true } { pop false } ifelse
  359. } bind
  360. /ResourceForAll {
  361. % **************** Doesn't present instance groups in
  362. % **************** the correct order yet.
  363. % Construct a new procedure to hold the arguments.
  364. % All objects constructed here must be in local VM to avoid
  365. % a possible invalidaccess.
  366. currentdict 4 .localpackedarray % [template proc scratch resdict]
  367. % We must pop the resource dictionary off the dict stack
  368. % when doing the actual iteration, and restore it afterwards.
  369. .currentglobal not {
  370. .LocalInstances length 0 ne {
  371. % We must do local instances, and do them first.
  372. //.localresourceforall {exec} 0 get 3 .localpackedarray cvx
  373. .LocalInstances exch {forall} 0 get 1 index 0 get
  374. currentdict end 3 .execn begin
  375. } if
  376. } if
  377. % Do global instances next.
  378. //.globalresourceforall {exec} 0 get 3 .localpackedarray cvx
  379. .Instances exch cvx {forall} 0 get 1 index 0 get
  380. currentdict end 3 .execn begin
  381. currentdict /ResourceFileName known {
  382. % Finally, do instances stored on files.
  383. dup 0 get 100 string ResourceFileName
  384. dup length 2 index 0 get length sub 3 -1 roll
  385. //.externalresourceforall {exec} 0 get 4 .localpackedarray cvx
  386. 100 string {filenameforall} 0 get
  387. currentdict end 2 .execn begin null % for pop
  388. } if pop
  389. } bind
  390. /ResourceFileName
  391. { /GenericResourceDir getsystemparam
  392. Category .namestring concatstrings
  393. /GenericResourcePathSep getsystemparam concatstrings
  394. .genericrfn
  395. } bind
  396. % Additional entries
  397. % Unfortunately, we can't create the real .Instances dictionary now,
  398. % because if someone copies the Generic category (which pp. 95-96 of the
  399. % 2nd Edition Red Book says is legitimate), they'll wind up sharing
  400. % the .Instances. Instead, we have to create .Instances on demand,
  401. % just like the entry in localinstancedict.
  402. % We also have to prevent anyone from creating instances of Generic itself.
  403. /.Instances //.emptydict
  404. /.LocalInstances
  405. { localinstancedict Category .knownget not { //.emptydict } if
  406. } bind
  407. /.GetInstance
  408. { currentglobal
  409. { .Instances exch .knownget }
  410. { .LocalInstances 1 index .knownget
  411. { exch pop true }
  412. { .Instances exch .knownget }
  413. ifelse
  414. }
  415. ifelse
  416. } bind
  417. /.CheckResource
  418. { true
  419. } bind
  420. /.vmused {
  421. % - .vmused <usedvalue>
  422. % usedvalue = vmstatus in global + vmstatus in local.
  423. 0 2 {
  424. .currentglobal not .setglobal
  425. vmstatus pop exch pop add
  426. } repeat
  427. } bind def
  428. /.DoLoadResource {
  429. % .LoadResource may push entries on the operand stack.
  430. % It is an undocumented feature of Adobe implementations,
  431. % which we must match for the sake of some badly written
  432. % font downloading code, that such entries are popped
  433. % automatically.
  434. count 1 index cvlit .vmused
  435. % Stack: key count litkey memused
  436. {.LoadResource} 4 1 roll 4 .execn
  437. % Stack: ... count key memused
  438. .vmused exch sub
  439. 1 index .getvminstance not {
  440. pop dup /undefinedresource signalerror % didn't load
  441. } if
  442. dup 1 1 put
  443. 2 3 -1 roll put
  444. % Stack: ... count key
  445. exch count 1 sub exch sub {exch pop} repeat
  446. } bind
  447. /.LoadResource
  448. { dup .ResourceFile
  449. { exch pop currentglobal
  450. { .runresource }
  451. { true setglobal { .runresource } stopped false setglobal { stop } if }
  452. ifelse
  453. }
  454. { dup /undefinedresource signalerror
  455. }
  456. ifelse
  457. } bind
  458. /.ResourceFile
  459. { currentdict /ResourceFileName known
  460. { mark 1 index 100 string { ResourceFileName }
  461. .internalstopped
  462. { cleartomark false }
  463. { exch pop findlibfile
  464. { exch pop exch pop true }
  465. { pop false }
  466. ifelse
  467. }
  468. ifelse
  469. }
  470. { false }
  471. ifelse
  472. } bind
  473. .dicttomark
  474. /Category defineresource pop
  475. % Fill in the rest of the Category category.
  476. /Category /Category findresource dup
  477. /Generic /Category findresource begin {
  478. /FindResource /ResourceForAll /ResourceStatus /.ResourceFileStatus
  479. /UndefineResource /ResourceFileName
  480. /.ResourceFile /.LoadResource /.DoLoadResource
  481. } { dup load put dup } forall
  482. pop readonly pop end
  483. (END GENERIC) VMDEBUG
  484. % Define the fixed categories.
  485. mark
  486. % Non-Type categories with existing entries.
  487. /ColorSpaceFamily
  488. { } % These must be deferred, because optional features may add some.
  489. /Emulator
  490. mark EMULATORS { cvn } forall .packtomark
  491. /Filter
  492. { } % These must be deferred, because optional features may add some.
  493. /IODevice
  494. % Loop until the .getiodevice gets a rangecheck.
  495. errordict /rangecheck 2 copy get
  496. errordict /rangecheck { pop stop } put % pop the command
  497. mark 0 { {
  498. dup .getiodevice dup null eq { pop } { exch } ifelse 1 add
  499. } loop} .internalstopped
  500. pop pop pop .packtomark
  501. 4 1 roll put
  502. .clearerror
  503. % Type categories listed in the Red Book.
  504. /ColorRenderingType
  505. { } % These must be deferred, because optional features may add some.
  506. /FMapType
  507. { } % These must be deferred, because optional features may add some.
  508. /FontType
  509. { } % These must be deferred, because optional features may add some.
  510. /FormType
  511. { } % These must be deferred, because optional features may add some.
  512. /HalftoneType
  513. { } % These must be deferred, because optional features may add some.
  514. /ImageType
  515. { } % Deferred, optional features may add some.
  516. /PatternType
  517. { } % Deferred, optional features may add some.
  518. % Type categories added since the Red Book.
  519. /setsmoothness where {
  520. pop /ShadingType { } % Deferred, optional features may add some.
  521. } if
  522. counttomark 2 idiv
  523. { mark
  524. % Standard entries
  525. % We'd like to prohibit defineresource,
  526. % but because optional features may add entries, we can't.
  527. % We can at least require that the key and value match.
  528. /DefineResource
  529. { currentglobal not
  530. { /defineresource load /invalidaccess signalerror }
  531. { 2 copy ne
  532. { /defineresource load /rangecheck signalerror }
  533. { dup .Instances 4 -2 roll .growput }
  534. ifelse
  535. }
  536. ifelse
  537. } bind
  538. /UndefineResource
  539. { /undefineresource load /invalidaccess signalerror } bind
  540. /FindResource
  541. { .Instances 1 index .knownget
  542. { exch pop }
  543. { /findresource load /undefinedresource signalerror }
  544. ifelse
  545. } bind
  546. /ResourceStatus
  547. { .Instances exch known { 0 0 true } { false } ifelse } bind
  548. /ResourceForAll
  549. /Generic /Category findresource /ResourceForAll get
  550. % Additional entries
  551. counttomark 2 add -1 roll
  552. dup length dict dup begin exch { dup def } forall end
  553. % We'd like to make the .Instances readonly here,
  554. % but because optional features may add entries, we can't.
  555. /.Instances exch
  556. /.LocalInstances % used by ResourceForAll
  557. 0 dict def
  558. .dicttomark /Category defineresource pop
  559. } repeat pop
  560. (END FIXED) VMDEBUG
  561. % Define the other built-in categories.
  562. /.definecategory % <name> -mark- <key1> ... <valuen> .definecategory -
  563. { counttomark 2 idiv 2 add % .Instances, Category
  564. /Generic /Category findresource dup maxlength 3 -1 roll add
  565. dict .copydict begin
  566. counttomark 2 idiv { def } repeat pop % pop the mark
  567. currentdict end /Category defineresource pop
  568. } bind def
  569. /ColorRendering mark /InstanceType /dicttype .definecategory
  570. % ColorSpace is defined below
  571. % Encoding is defined below
  572. % Font is defined below
  573. /Form mark /InstanceType /dicttype .definecategory
  574. /Halftone mark /InstanceType /dicttype .definecategory
  575. /Pattern mark /InstanceType /dicttype .definecategory
  576. /ProcSet mark /InstanceType /dicttype .definecategory
  577. % Added since the Red Book:
  578. /ControlLanguage mark /InstanceType /dicttype .definecategory
  579. /HWOptions mark /InstanceType /dicttype .definecategory
  580. /Localization mark /InstanceType /dicttype .definecategory
  581. /OutputDevice mark /InstanceType /dicttype .definecategory
  582. /PDL mark /InstanceType /dicttype .definecategory
  583. % CIDFont, CIDMap, and CMap are defined in gs_cidfn.ps
  584. % FontSet is defined in gs_cff.ps
  585. % IdiomSet is defined in gs_ll3.ps
  586. % InkParams and TrapParams are defined in gs_trap.ps
  587. (END MISC) VMDEBUG
  588. % Define the ColorSpace category.
  589. /.defaultcsnames mark
  590. /DefaultGray 0
  591. /DefaultRGB 1
  592. /DefaultCMYK 2
  593. .dicttomark readonly def
  594. % The "hooks" are no-ops here, redefined in LL3.
  595. /.definedefaultcs { % <index> <value> .definedefaultcs -
  596. pop pop
  597. } bind def
  598. /.undefinedefaultcs { % <index> .undefinedefaultcs -
  599. pop
  600. } bind def
  601. /ColorSpace mark
  602. /InstanceType /arraytype
  603. % We keep track of whether there are any local definitions for any of
  604. % the Default keys. This information must get saved and restored in
  605. % parallel with the local instance dictionary, so it must be stored in
  606. % local VM.
  607. userdict /.localcsdefaults false put
  608. /DefineResource {
  609. 2 copy /Generic /Category findresource /DefineResource get exec
  610. exch pop
  611. exch //.defaultcsnames exch .knownget {
  612. 1 index .definedefaultcs
  613. currentglobal not { .userdict /.localcsdefaults true put } if
  614. } if
  615. } bind
  616. /UndefineResource {
  617. dup /Generic /Category findresource /UndefineResource get exec
  618. //.defaultcsnames 1 index .knownget {
  619. % Stack: resname index
  620. currentglobal {
  621. .undefinedefaultcs pop
  622. } {
  623. % We removed the local definition, but there might be a global one.
  624. exch .GetInstance {
  625. 0 get .definedefaultcs
  626. } {
  627. .undefinedefaultcs
  628. } ifelse
  629. % Recompute .localcsdefaults by scanning. This is rarely needed.
  630. .userdict /.localcsdefaults false //.defaultcsnames {
  631. pop .LocalInstances exch known { pop true exit } if
  632. } forall put
  633. } ifelse
  634. } {
  635. pop
  636. } ifelse
  637. } bind
  638. .definecategory % ColorSpace
  639. % Define the Encoding category.
  640. /Encoding mark
  641. /InstanceType /arraytype
  642. % Handle already-registered encodings, including lazily loaded encodings
  643. % that aren't loaded yet.
  644. /.Instances mark
  645. EncodingDirectory
  646. { dup length 256 eq { [ exch readonly 0 -1 ] } { pop [null 2 -1] } ifelse
  647. } forall
  648. .dicttomark
  649. /.ResourceFileDict mark
  650. EncodingDirectory
  651. { dup length 256 eq { pop pop } { 0 get } ifelse
  652. } forall
  653. .dicttomark
  654. /ResourceFileName
  655. { .ResourceFileDict 2 index .knownget
  656. { exch copy exch pop }
  657. { /Generic /Category findresource /ResourceFileName get exec }
  658. ifelse
  659. } bind
  660. .definecategory % Encoding
  661. % Make placeholders in level2dict for the redefined Encoding operators,
  662. % so that they will be swapped properly when we switch language levels.
  663. /.findencoding /.findencoding load def
  664. /findencoding /findencoding load def
  665. /.defineencoding /.defineencoding load def
  666. (END ENCODING) VMDEBUG
  667. % Define the Font category.
  668. /.fontstatus { % <fontname> .fontstatus <fontname> <found>
  669. { % Create a loop context just so we can exit it early.
  670. % Check Fontmap.
  671. Fontmap 1 index .knownget {
  672. {
  673. dup type /nametype eq {
  674. .fontstatus { pop null exit } if
  675. } {
  676. dup type /stringtype eq {
  677. findlibfile { closefile pop null exit } if pop
  678. } {
  679. % Procedure, assume success.
  680. pop null exit
  681. } ifelse
  682. } ifelse
  683. } forall dup null eq { pop true exit } if
  684. } if
  685. % Convert names to strings; give up on other types.
  686. dup type /nametype eq { .namestring } if
  687. dup type /stringtype ne { false exit } if
  688. % Check the resource directory.
  689. dup .fonttempstring /FontResourceDir getsystemparam .genericrfn
  690. status {
  691. pop pop pop pop true exit
  692. } if
  693. % Check for a file on the search path with the same name
  694. % as the font.
  695. findlibfile { closefile true exit } if
  696. % Scan a FONTPATH directory and try again.
  697. .scannextfontdir not { false exit } if
  698. } loop
  699. } bind def
  700. /Font mark
  701. /InstanceType /dicttype
  702. /DefineResource
  703. { 2 copy //definefont exch pop
  704. /Generic /Category findresource /DefineResource get exec
  705. } bind
  706. /UndefineResource
  707. { dup //undefinefont
  708. /Generic /Category findresource /UndefineResource get exec
  709. } bind
  710. /FindResource {
  711. dup .getvminstance {
  712. exch pop 0 get
  713. } {
  714. dup ResourceStatus {
  715. pop 1 gt { .loadfontresource } { .GetInstance pop 0 get } ifelse
  716. } {
  717. .loadfontresource
  718. } ifelse
  719. } ifelse
  720. } bind
  721. /ResourceForAll {
  722. { .scannextfontdir not { exit } if } loop
  723. /Generic /Category findresource /ResourceForAll get exec
  724. } bind
  725. /.ResourceFileStatus {
  726. .fontstatus { pop 2 -1 true } { pop false } ifelse
  727. } bind
  728. /.loadfontresource {
  729. dup vmstatus pop exch pop exch
  730. % Hack: rebind .currentresourcefile so that all calls of
  731. % definefont will know these are built-in fonts.
  732. currentfile {pop //findfont exec} .execasresource % (findfont is a procedure)
  733. exch vmstatus pop exch pop exch sub
  734. % stack: name font vmused
  735. % findfont has the prerogative of not calling definefont
  736. % in certain obscure cases of font substitution.
  737. 2 index .getvminstance {
  738. dup 1 1 put
  739. 2 3 -1 roll put
  740. } {
  741. pop
  742. } ifelse exch pop
  743. } bind
  744. /.Instances FontDirectory length 2 mul dict
  745. .definecategory % Font
  746. % Redefine font "operators".
  747. /.definefontmap
  748. { /Font /Category findresource /.Instances get
  749. dup 3 index known
  750. { pop
  751. }
  752. { 2 index
  753. % Make sure we create the array in global VM.
  754. .currentglobal true .setglobal
  755. [null 2 -1] exch .setglobal
  756. .growput
  757. }
  758. ifelse
  759. //.definefontmap exec
  760. } bind def
  761. % Make sure the old definitions are still in systemdict so that
  762. % they will get bound properly.
  763. systemdict begin
  764. /.origdefinefont /definefont load def
  765. /.origundefinefont /undefinefont load def
  766. /.origfindfont /findfont load def
  767. end
  768. /definefont {
  769. /Font defineresource
  770. } bind odef
  771. /undefinefont {
  772. /Font undefineresource
  773. } bind odef
  774. % The Red Book requires that findfont be a procedure, not an operator,
  775. % but it still needs to restore the stacks reliably if it fails.
  776. /.findfontop {
  777. /Font findresource
  778. } bind odef
  779. /findfont {
  780. .findfontop
  781. } bind def % Must be a procedure, not an operator
  782. % Remove initialization utilities.
  783. currentdict /.definecategory .undef
  784. currentdict /.emptydict .undef
  785. end % level2dict
  786. % Convert deferred resources after we finally switch to Level 2.
  787. /.fixresources {
  788. % Encoding resources
  789. EncodingDirectory
  790. { dup length 256 eq
  791. { /Encoding defineresource pop }
  792. { pop pop }
  793. ifelse
  794. } forall
  795. /.findencoding { /Encoding findresource } bind def
  796. /findencoding /.findencoding load def % must be a procedure
  797. /.defineencoding { /Encoding defineresource pop } bind def
  798. % ColorRendering resources and ProcSet
  799. systemdict /ColorRendering .knownget {
  800. /ColorRendering exch /ProcSet defineresource pop
  801. systemdict /ColorRendering undef
  802. /Default currentcolorrendering /ColorRendering defineresource pop
  803. } if
  804. % ColorSpace resources
  805. systemdict /CIEsRGB .knownget {
  806. /sRGB exch /ColorSpace defineresource pop
  807. systemdict /CIEsRGB undef
  808. } if
  809. % ColorSpaceFamily resources
  810. colorspacedict { pop dup /ColorSpaceFamily defineresource pop } forall
  811. % Filter resources
  812. filterdict { pop dup /Filter defineresource pop } forall
  813. % FontType and FMapType resources
  814. buildfontdict { pop dup /FontType defineresource pop } forall
  815. mark
  816. buildfontdict 0 known { 2 3 4 5 6 7 8 } if
  817. buildfontdict 9 known { 9 } if
  818. counttomark { dup /FMapType defineresource pop } repeat pop
  819. % FormType resources
  820. .formtypes { pop dup /FormType defineresource pop } forall
  821. % HalftoneType resources
  822. .halftonetypes { pop dup /HalftoneType defineresource pop } forall
  823. % ColorRenderingType resources
  824. .colorrenderingtypes {pop dup /ColorRenderingType defineresource pop} forall
  825. % ImageType resources
  826. .imagetypes { pop dup /ImageType defineresource pop } forall
  827. % PatternType resources
  828. .patterntypes { pop dup /PatternType defineresource pop } forall
  829. % Make the fixed resource categories immutable.
  830. /.shadingtypes where {
  831. pop .shadingtypes { pop dup /ShadingType defineresource pop } forall
  832. } if
  833. [ /ColorSpaceFamily /Emulator /Filter /IODevice /ColorRenderingType
  834. /FMapType /FontType /FormType /HalftoneType /ImageType /PatternType
  835. /.shadingtypes where { pop /ShadingType } if
  836. ] {
  837. /Category findresource
  838. dup /.Instances get readonly pop
  839. .LocalInstances readonly pop
  840. readonly pop
  841. } forall
  842. % clean up
  843. systemdict /.fixresources undef
  844. } bind def