星火微课系统客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

gs_res.ps 37KB

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