gs_res.ps 34 KB

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