home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 April / PCWorld_2001-04_cd.bin / Software / Vyzkuste / gs / gs650w32.exe / gs6.50 / lib / gs_res.ps < prev    next >
Text File  |  2000-12-05  |  29KB  |  922 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.13.2.1 2000/11/09 18:54:57 rayjj 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. /.DoLoadResource {
  454.         % .LoadResource may push entries on the operand stack.
  455.         % It is an undocumented feature of Adobe implementations,
  456.         % which we must match for the sake of some badly written
  457.         % font downloading code, that such entries are popped
  458.         % automatically.
  459.     count 1 index cvlit vmstatus pop exch pop
  460.         % Stack: key count litkey memused
  461.     {.LoadResource} 4 1 roll 4 .execn
  462.         % Stack: ... count key memused
  463.     vmstatus pop exch pop exch sub
  464.     1 index .getvminstance not {
  465.       pop dup /undefinedresource signalerror    % didn't load
  466.     } if
  467.     dup 1 1 put
  468.     2 3 -1 roll put
  469.         % Stack: ... count key
  470.     exch count 1 sub exch sub {exch pop} repeat
  471. } bind
  472. /.LoadResource
  473.     { dup .ResourceFile
  474.        { exch pop currentglobal
  475.           { .runresource }
  476.           { true setglobal { .runresource } stopped false setglobal { stop } if }
  477.          ifelse
  478.        }
  479.        { dup /undefinedresource signalerror
  480.        }
  481.      ifelse
  482.     } bind
  483. /.ResourceFile
  484.     { currentdict /ResourceFileName known
  485.        { mark 1 index 100 string { ResourceFileName }
  486.          .internalstopped
  487.           { cleartomark false }
  488.           { exch pop findlibfile
  489.          { exch pop exch pop true }
  490.          { pop false }
  491.         ifelse
  492.           }
  493.          ifelse
  494.        }
  495.        { false }
  496.       ifelse
  497.     } bind
  498.  
  499. .dicttomark
  500. /Category defineresource pop
  501.  
  502. % Fill in the rest of the Category category.
  503. /Category /Category findresource dup
  504. /Generic /Category findresource begin {
  505.   /FindResource /ResourceForAll /ResourceStatus /.ResourceFileStatus
  506.   /UndefineResource /ResourceFileName
  507.   /.ResourceFile /.LoadResource /.DoLoadResource
  508. } { dup load put dup } forall
  509. pop readonly pop end
  510.  
  511. (END GENERIC) VMDEBUG
  512.  
  513. % Define the fixed categories.
  514.  
  515. mark
  516.     % Non-Type categories with existing entries.
  517.  /ColorSpaceFamily
  518.    { }    % These must be deferred, because optional features may add some.
  519.  /Emulator
  520.    mark EMULATORS { cvn } forall .packtomark
  521.  /Filter
  522.    { }    % These must be deferred, because optional features may add some.
  523.  /IODevice
  524.     % Loop until the .getiodevice gets a rangecheck.
  525.    errordict /rangecheck 2 copy get
  526.    errordict /rangecheck { pop stop } put    % pop the command
  527.    mark 0 { {
  528.     dup .getiodevice dup null eq { pop } { exch } ifelse 1 add
  529.    } loop} .internalstopped
  530.    pop pop pop .packtomark
  531.    4 1 roll put
  532.    .clearerror
  533.     % Type categories listed in the Red Book.
  534.  /ColorRenderingType
  535.    { }    % These must be deferred, because optional features may add some.
  536.  /FMapType
  537.    { }    % These must be deferred, because optional features may add some.
  538.  /FontType
  539.    { }    % These must be deferred, because optional features may add some.
  540.  /FormType
  541.    { }    % These must be deferred, because optional features may add some.
  542.  /HalftoneType
  543.    { }    % These must be deferred, because optional features may add some.
  544.  /ImageType
  545.    { }    % Deferred, optional features may add some.
  546.  /PatternType
  547.    { }  % Deferred, optional features may add some.
  548.     % Type categories added since the Red Book.
  549.  /setsmoothness where {
  550.    pop /ShadingType { }    % Deferred, optional features may add some.
  551.  } if
  552. counttomark 2 idiv
  553.  { mark
  554.  
  555.         % Standard entries
  556.  
  557.         % We'd like to prohibit defineresource,
  558.         % but because optional features may add entries, we can't.
  559.         % We can at least require that the key and value match.
  560.    /DefineResource
  561.     { currentglobal not
  562.        { /defineresource load /invalidaccess signalerror }
  563.        { 2 copy ne
  564.           { /defineresource load /rangecheck signalerror }
  565.           { dup .Instances 4 -2 roll .growput }
  566.          ifelse
  567.        }
  568.       ifelse
  569.     } bind
  570.    /UndefineResource
  571.     { /undefineresource load /invalidaccess signalerror } bind
  572.    /FindResource
  573.     { .Instances 1 index .knownget
  574.        { exch pop }
  575.        { /findresource load /undefinedresource signalerror }
  576.       ifelse
  577.     } bind
  578.    /ResourceStatus
  579.     { .Instances exch known { 0 0 true } { false } ifelse } bind
  580.    /ResourceForAll
  581.     /Generic /Category findresource /ResourceForAll get
  582.  
  583.         % Additional entries
  584.  
  585.    counttomark 2 add -1 roll
  586.    dup length dict dup begin exch { dup def } forall end
  587.         % We'd like to make the .Instances readonly here,
  588.         % but because optional features may add entries, we can't.
  589.    /.Instances exch
  590.    /.LocalInstances    % used by ResourceForAll
  591.     0 dict def
  592.  
  593.    .dicttomark /Category defineresource pop
  594.  } repeat pop
  595.  
  596. (END FIXED) VMDEBUG
  597.  
  598. % Define the other built-in categories.
  599.  
  600. /.definecategory    % <name> -mark- <key1> ... <valuen> .definecategory -
  601.  { counttomark 2 idiv 2 add        % .Instances, Category
  602.    /Generic /Category findresource dup maxlength 3 -1 roll add
  603.    dict .copydict begin
  604.    counttomark 2 idiv { def } repeat pop    % pop the mark
  605.    currentdict end /Category defineresource pop
  606.  } bind def
  607.  
  608. /ColorRendering mark /InstanceType /dicttype .definecategory
  609. % ColorSpace is defined below
  610. % Encoding is defined below
  611. % Font is defined below
  612. /Form mark /InstanceType /dicttype .definecategory
  613. /Halftone mark /InstanceType /dicttype .definecategory
  614. /Pattern mark /InstanceType /dicttype .definecategory
  615. /ProcSet mark /InstanceType /dicttype .definecategory
  616. % Added since the Red Book:
  617. /ControlLanguage mark /InstanceType /dicttype .definecategory
  618. /HWOptions mark /InstanceType /dicttype .definecategory
  619. /Localization mark /InstanceType /dicttype .definecategory
  620. /OutputDevice mark /InstanceType /dicttype .definecategory
  621. /PDL mark /InstanceType /dicttype .definecategory
  622. % CIDFont, CIDMap, and CMap are defined in gs_cidfn.ps
  623. % FontSet is defined in gs_cff.ps
  624. % IdiomSet is defined in gs_ll3.ps
  625. % InkParams and TrapParams are defined in gs_trap.ps
  626.  
  627. (END MISC) VMDEBUG
  628.  
  629. % Define the ColorSpace category.
  630.  
  631. /.defaultcsnames mark
  632.   /DefaultGray 0
  633.   /DefaultRGB 1
  634.   /DefaultCMYK 2
  635. .dicttomark readonly def
  636.  
  637. % The "hooks" are no-ops here, redefined in LL3.
  638. /.definedefaultcs {    % <index> <value> .definedefaultcs -
  639.   pop pop
  640. } bind def
  641. /.undefinedefaultcs {    % <index> .undefinedefaultcs -
  642.   pop
  643. } bind def
  644.  
  645. /ColorSpace mark
  646.  
  647. /InstanceType /arraytype
  648.  
  649. % We keep track of whether there are any local definitions for any of
  650. % the Default keys.  This information must get saved and restored in
  651. % parallel with the local instance dictionary, so it must be stored in
  652. % local VM.
  653. userdict /.localcsdefaults false put
  654.  
  655. /DefineResource {
  656.   2 copy /Generic /Category findresource /DefineResource get exec
  657.   exch pop
  658.   exch //.defaultcsnames exch .knownget {
  659.     1 index .definedefaultcs
  660.     currentglobal not { .userdict /.localcsdefaults true put } if
  661.   } if
  662. } bind
  663.  
  664. /UndefineResource {
  665.   dup /Generic /Category findresource /UndefineResource get exec
  666.   //.defaultcsnames 1 index .knownget {
  667.     % Stack: resname index
  668.     currentglobal {
  669.       .undefinedefaultcs pop
  670.     } {
  671.     % We removed the local definition, but there might be a global one.
  672.       exch .GetInstance {
  673.     0 get .definedefaultcs
  674.       } {
  675.     .undefinedefaultcs
  676.       } ifelse
  677.     % Recompute .localcsdefaults by scanning.  This is rarely needed.
  678.       .userdict /.localcsdefaults false //.defaultcsnames {
  679.     pop .LocalInstances exch known { pop true exit } if
  680.       } forall put
  681.     } ifelse
  682.   } {
  683.     pop
  684.   } ifelse
  685. } bind
  686.  
  687. .definecategory            % ColorSpace
  688.  
  689. % Define the Encoding category.
  690.  
  691. /Encoding mark
  692.  
  693. /InstanceType /arraytype
  694.  
  695. % Handle already-registered encodings, including lazily loaded encodings
  696. % that aren't loaded yet.
  697.  
  698. /.Instances mark
  699.   EncodingDirectory
  700.    { dup length 256 eq { [ exch readonly 0 -1 ] } { pop [null 2 -1] } ifelse
  701.    } forall
  702. .dicttomark
  703.  
  704. /.ResourceFileDict mark
  705.   EncodingDirectory
  706.    { dup length 256 eq { pop pop } { 0 get } ifelse
  707.    } forall
  708. .dicttomark
  709.  
  710. /ResourceFileName
  711.  { .ResourceFileDict 2 index .knownget
  712.     { exch copy exch pop }
  713.     { /Generic /Category findresource /ResourceFileName get exec }
  714.    ifelse
  715.  } bind
  716.  
  717. .definecategory            % Encoding
  718.  
  719. % Make placeholders in level2dict for the redefined Encoding operators,
  720. % so that they will be swapped properly when we switch language levels.
  721.  
  722. /.findencoding /.findencoding load def
  723. /findencoding /findencoding load def
  724. /.defineencoding /.defineencoding load def
  725.  
  726. (END ENCODING) VMDEBUG
  727.  
  728. % Define the Font category.
  729.  
  730. /.fontstatus {        % <fontname> .fontstatus <fontname> <found>
  731.   {        % Create a loop context just so we can exit it early.
  732.         % Check Fontmap.
  733.     Fontmap 1 index .knownget {
  734.       {
  735.     dup type /nametype eq {
  736.       .fontstatus { null exit } if
  737.     } {
  738.       dup type /stringtype eq {
  739.         findlibfile { closefile pop null exit } if pop
  740.       } {
  741.         % Procedure, assume success.
  742.         pop null exit
  743.       } ifelse
  744.     } ifelse
  745.       } forall dup null eq { pop true exit } if
  746.     } if
  747.         % Convert names to strings; give up on other types.
  748.     dup type /nametype eq { .namestring } if
  749.     dup type /stringtype ne { false exit } if
  750.         % Check the resource directory.
  751.     dup .fonttempstring /FontResourceDir getsystemparam .genericrfn
  752.     status {
  753.       pop pop pop pop true exit
  754.     } if
  755.         % Check for a file on the search path with the same name
  756.         % as the font.
  757.     findlibfile { closefile true exit } if
  758.         % Scan a FONTPATH directory and try again.
  759.     .scannextfontdir not { false exit } if
  760.   } loop
  761. } bind def
  762.  
  763. /Font mark
  764.  
  765. /InstanceType /dicttype
  766.  
  767. /DefineResource
  768.     { 2 copy //definefont exch pop
  769.       /Generic /Category findresource /DefineResource get exec
  770.     } bind
  771. /UndefineResource
  772.     { dup //undefinefont
  773.       /Generic /Category findresource /UndefineResource get exec
  774.     } bind
  775. /FindResource {
  776.     dup .getvminstance {
  777.       exch pop 0 get
  778.     } {
  779.       dup ResourceStatus {
  780.         pop 1 gt { .loadfontresource } { .GetInstance pop 0 get } ifelse
  781.       } {
  782.         .loadfontresource
  783.       } ifelse
  784.     } ifelse
  785. } bind
  786. /ResourceForAll {
  787.     { .scannextfontdir not { exit } if } loop
  788.     /Generic /Category findresource /ResourceForAll get exec
  789. } bind
  790. /.ResourceFileStatus {
  791.     .fontstatus { pop 2 -1 true } { pop false } ifelse
  792. } bind
  793.  
  794. /.loadfontresource {
  795.     dup vmstatus pop exch pop exch
  796.         % Hack: rebind .currentresourcefile so that all calls of
  797.         % definefont will know these are built-in fonts.
  798.     currentfile {pop //findfont exec} .execasresource  % (findfont is a procedure)
  799.     exch vmstatus pop exch pop exch sub
  800.         % stack: name font vmused
  801.         % findfont has the prerogative of not calling definefont
  802.         % in certain obscure cases of font substitution.
  803.     2 index .getvminstance {
  804.       dup 1 1 put
  805.       2 3 -1 roll put
  806.     } {
  807.       pop
  808.     } ifelse exch pop
  809. } bind
  810.  
  811. /.Instances FontDirectory length 2 mul dict
  812.  
  813. .definecategory            % Font
  814.  
  815. % Redefine font "operators".
  816. /.definefontmap
  817.  { /Font /Category findresource /.Instances get
  818.    dup 3 index known
  819.     { pop
  820.     }
  821.     { 2 index
  822.         % Make sure we create the array in global VM.
  823.       .currentglobal true .setglobal
  824.       [null 2 -1] exch .setglobal
  825.       .growput
  826.     }
  827.    ifelse
  828.    //.definefontmap exec
  829.  } bind def
  830.  
  831. % Make sure the old definitions are still in systemdict so that
  832. % they will get bound properly.
  833. systemdict begin
  834.   /.origdefinefont /definefont load def
  835.   /.origundefinefont /undefinefont load def
  836.   /.origfindfont /findfont load def
  837. end
  838. /definefont {
  839.   /Font defineresource
  840. } bind odef
  841. /undefinefont {
  842.   /Font undefineresource
  843. } bind odef
  844. % The Red Book requires that findfont be a procedure, not an operator,
  845. % but it still needs to restore the stacks reliably if it fails.
  846. /.findfontop {
  847.   /Font findresource
  848. } bind odef
  849. /findfont {
  850.   .findfontop
  851. } bind def    % Must be a procedure, not an operator
  852.  
  853. % Remove initialization utilities.
  854. currentdict /.definecategory .undef
  855. currentdict /.emptydict .undef
  856.  
  857. end                % level2dict
  858.  
  859. % Convert deferred resources after we finally switch to Level 2.
  860.  
  861. /.fixresources {
  862.     % Encoding resources
  863.   EncodingDirectory
  864.    { dup length 256 eq
  865.       { /Encoding defineresource pop }
  866.       { pop pop }
  867.      ifelse
  868.    } forall
  869.   /.findencoding { /Encoding findresource } bind def
  870.   /findencoding /.findencoding load def        % must be a procedure
  871.   /.defineencoding { /Encoding defineresource pop } bind def
  872.     % ColorRendering resources and ProcSet
  873.   systemdict /ColorRendering .knownget {
  874.     /ColorRendering exch /ProcSet defineresource pop
  875.     systemdict /ColorRendering undef
  876.     /Default currentcolorrendering /ColorRendering defineresource pop
  877.   } if
  878.     % ColorSpace resources
  879.   systemdict /CIEsRGB .knownget {
  880.     /sRGB exch /ColorSpace defineresource pop
  881.     systemdict /CIEsRGB undef
  882.   } if
  883.     % ColorSpaceFamily resources
  884.   colorspacedict { pop dup /ColorSpaceFamily defineresource pop } forall
  885.     % Filter resources
  886.   filterdict { pop dup /Filter defineresource pop } forall
  887.     % FontType and FMapType resources
  888.   buildfontdict { pop dup /FontType defineresource pop } forall
  889.   mark
  890.     buildfontdict 0 known { 2 3 4 5 6 7 8 } if
  891.     buildfontdict 9 known { 9 } if
  892.   counttomark { dup /FMapType defineresource pop } repeat pop
  893.     % FormType resources
  894.   .formtypes { pop dup /FormType defineresource pop } forall
  895.     % HalftoneType resources
  896.   .halftonetypes { pop dup /HalftoneType defineresource pop } forall
  897.     % ColorRenderingType resources
  898.   .colorrenderingtypes {pop dup /ColorRenderingType defineresource pop} forall
  899.     % ImageType resources
  900.   .imagetypes { pop dup /ImageType defineresource pop } forall
  901.     % PatternType resources
  902.   .patterntypes { pop dup /PatternType defineresource pop } forall
  903.     % Make the fixed resource categories immutable.
  904.   /.shadingtypes where {
  905.     pop .shadingtypes { pop dup /ShadingType defineresource pop } forall
  906.   } if
  907.   [ /ColorSpaceFamily /Emulator /Filter /IODevice /ColorRenderingType
  908.     /FMapType /FontType /FormType /HalftoneType /ImageType /PatternType
  909.     /.shadingtypes where { pop /ShadingType } if
  910.   ] {
  911.     /Category findresource
  912.     dup /.Instances get readonly pop
  913.     .LocalInstances readonly pop
  914.     readonly pop
  915.   } forall
  916.     % clean up
  917.   systemdict /.fixresources undef
  918. } bind def
  919.