home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 October / Chip_2002-10_cd1.bin / zkuste / pdf / download / gs704w32.exe / gs7.04 / lib / gs_res.ps < prev    next >
Encoding:
Text File  |  2002-01-31  |  29.3 KB  |  930 lines

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