% Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000 Aladdin Enterprises. All rights reserved.% % This file is part of Aladdin Ghostscript.% % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author% or distributor accepts any responsibility for the consequences of using it,% or for whether it serves any particular purpose or works at all, unless he% or she says so in writing. Refer to the Aladdin Ghostscript Free Public% License (the "License") for full details.% % Every copy of Aladdin Ghostscript must include a copy of the License,% normally in a plain ASCII text file named PUBLIC. The License grants you% the right to copy, modify and redistribute Aladdin Ghostscript, but only% under certain conditions described in the License. Among other things, the% License requires that the copyright notice and this notice be preserved on% all copies. % $Id: gs_res.ps,v 1.2 2000/03/10 04:54:15 lpd Exp $% Initialization file for Level 2 resource machinery.% When this is run, systemdict is still writable,% but (almost) everything defined here goes into level2dict. level2dict begin (BEGIN RESOURCES) VMDEBUG % We keep track of (global) instances with another entry in the resource% dictionary, an Instances dictionary. For categories with implicit% instances, the values in Instances are the same as the keys;% for other categories, the values are [instance status size]. % Note that the dictionary that defines a resource category is stored% in global VM. The PostScript manual says that each category must% manage global and local instances separately. However, objects in% global VM other than systemdict can't reference objects in local VM.% This means that the resource category dictionary, which would otherwise be% the obvious place to keep track of the instances, can't be used to keep% track of local instances. Instead, we define a dictionary in local VM% called localinstancedict, in which the key is the category name and% the value is the analogue of Instances for local instances. % We don't currently implement automatic resource unloading.% When and if we do, it should be hooked to the garbage collector.% However, Ed Taft of Adobe says their interpreters don't implement this% either, so we aren't going to worry about it for a while. currentglobal false setglobal systemdict begin /localinstancedict 5 dict .forcedef % localinstancedict is local, systemdict is globalend true setglobal/.emptydict 0 dict readonly defsetglobal % Resource category dictionaries have the following keys (those marked with% * are optional):% Standard, defined in the Red Book:% Category (name)% *InstanceType (name)% DefineResource% <key> <instance> DefineResource <instance>% UndefineResource% <key> UndefineResource -% FindResource% <key> FindResource <instance>% ResourceStatus% <key> ResourceStatus <status> <size> true% <key> ResourceStatus false% ResourceForAll% <template> <proc> <scratch> ResourceForAll -% *ResourceFileName% <key> <scratch> ResourceFileName <filename>% Additional, specific to our implementation:% Instances (dictionary)% .LocalInstances% - .LocalInstances <dict>% .GetInstance% <key> .GetInstance <instance> -true-% <key> .GetInstance -false-% .CheckResource% <key> <value> .CheckResource <key> <value> <ok>% (or may give an error if not OK)% .DoLoadResource% <key> .DoLoadResource - (may give an error)% .LoadResource% <key> .LoadResource - (may give an error)% .ResourceFile% <key> .ResourceFile <file> -true-% <key> .ResourceFile <key> -false-% All the above procedures expect that the top dictionary on the d-stack% is the resource dictionary. % Define enough of the Category category so we can define other categories.% The dictionary we're about to create will become the Category% category definition dictionary. % .findcategory and .resourceexec are only called from within the% implementation of the resource 'operators', so they doesn't have to worry% about cleaning up the stack if they fail (the interpreter's stack% protection machinery for pseudo-operators takes care of this)./.findcategory { % <name> .findcategory - % (pushes the category on the dstack) /Category findresource begin} bind def /.resourceexec { % <key> /xxxResource .resourceexec - % (also pops the category from the dstack) load exec end} bind def 15 dict begin % Standard entries /Category /Category def/InstanceType /dicttype def /DefineResource { .CheckResource { dup /Category 3 index cvlit .growput % We would like to make Category dictionaries read-only, % and we used to do that here, but we can't do it, % because we have to be able to replace the dummy, empty % Instances dictionary with the real one later. dup [ exch 0 -1 ] exch Instances 4 2 roll put } { /defineresource load /typecheck signalerror } ifelse } bind def/FindResource % (redefined below) { Instances exch get 0 get } bind def % Additional entries /Instances 30 dict defInstances /Category [currentdict 0 -1] put /.LocalInstances 0 dict def/.GetInstance { Instances exch .knownget } bind def/.CheckResource { dup gcheck currentglobal and { /DefineResource /FindResource /ResourceForAll /ResourceStatus /UndefineResource } { 2 index exch known and } forall not { /defineresource load /invalidaccess signalerror } if true } bind def Instances end begin % for the base case of findresource (END CATEGORY) VMDEBUG % Define the resource operators. We use the "stack protection" feature of% odef to make sure the stacks are restored properly on an error.% This requires that the operators not pop anything from the stack until% they have executed their logic successfully. We can't make this% work for resourceforall, because the procedure it executes mustn't see% the operands of resourceforall on the stack, but we can make it work for% the others. mark/defineresource { % <key> <instance> <category> defineresource <instance> 3 copy .findcategory currentdict /InstanceType known { dup type InstanceType ne { dup type /packedarraytype eq InstanceType /arraytype eq and not { /defineresource load /typecheck signalerror } if } if } if /DefineResource .resourceexec 4 1 roll pop pop pop}/findresource { % <key> <category> findresource <instance> 2 copy dup /Category eq { pop //Category 0 get begin } { .findcategory } ifelse /FindResource .resourceexec exch pop exch pop}/resourceforall { % <template> <proc> <scratch> <category> resourceforall - dup /Category findresource begin /ResourceForAll load % Make sure we can recover the original operands. % Stack: ...operands... proc 5 copy pop 4 packedarray count % Stack: ...operands... proc saved count 4 -1 roll pop % pop the category /stopped load 3 1 roll 3 .execn % Stack: ... stopped saved count 3 -1 roll { % The count is the original stack depth + 2. count exch 4 sub sub { exch pop } repeat aload pop stop } { pop pop } ifelse end}/resourcestatus { % <key> <category> resourcestatus <status> <size> true % <key> <category> resourcestatus false 2 copy .findcategory /ResourceStatus .resourceexec { 4 2 roll pop pop true } { pop pop false } ifelse}/undefineresource { % <key> <category> undefineresource - 2 copy .findcategory /UndefineResource .resourceexec pop pop}end % Instances of Categorycounttomark 2 idiv { bind odef } repeat pop % Define the system parameters used for the Generic implementation of% ResourceFileName.systemdict begincurrentdict /pssystemparams known not { /pssystemparams 10 dict readonly def} ifpssystemparams begin /FontResourceDir (/Resource/Font/) readonly .forcedef % pssys'params is r-o /GenericResourceDir (/Resource/) readonly .forcedef % pssys'params is r-o /GenericResourcePathSep (/) readonly .forcedef % pssys'params is r-oendend % Define the generic algorithm for computing resource file names./.rfnstring 100 string def/.genericrfn % <key> <scratch> <prefix> .genericrfn <filename> { 3 -1 roll //.rfnstring cvs concatstrings exch copy } bind def % Define the Generic category. /Generic mark % Standard entries % We're still running in Level 1 mode, so dictionaries won't expand.% Leave room for the /Category entry./Category null /DefineResource { .CheckResource { dup [ exch 0 -1 ] % Stack: key value instance currentglobal { false setglobal 2 index UndefineResource % remove local def if any true setglobal Instances dup //.emptydict eq { pop 3 dict /Instances 1 index def } if } { .LocalInstances dup //.emptydict eq { pop 3 dict localinstancedict Category 2 index put } if } ifelse % Stack: key value instance instancedict 3 index 2 index .growput % Now make the resource value read-only. 0 2 copy get { readonly } .internalstopped pop dup 4 1 roll put exch pop exch pop } { /defineresource load /typecheck signalerror } ifelse } bind/UndefineResource { { dup 2 index .knownget { dup 1 get 1 ge { dup 0 null put 1 2 put pop pop } { pop exch .undef } ifelse } { pop pop } ifelse } currentglobal { 2 copy Instances exch exec } if .LocalInstances exch exec } bind/FindResource { dup ResourceStatus { pop 1 gt % not in VM { .DoLoadResource } if .GetInstance pop % can't fail 0 get } { /findresource load /undefinedresource signalerror } ifelse } bind/ResourceStatus { dup .GetInstance { exch pop dup 1 get exch 2 get true } { .ResourceFile { closefile 2 -1 true } { pop false } ifelse } ifelse } bind/ResourceForAll { % **************** Doesn't present instance groups in % **************** the correct order yet. % Construct a new procedure to hold the arguments. % It must be in local VM to avoid a possible invalidaccess. .currentglobal 4 1 roll false .setglobal 3 packedarray % template, proc, scratch { exch pop % stack contains: key, {template, proc, scratch} 2 copy 0 get .stringmatch { 1 index type dup /stringtype eq exch /nametype eq or { 2 copy 2 get cvs exch 1 get 3 -1 roll pop } { 1 get } ifelse exec } { pop pop } ifelse } /exec cvx 3 packedarray % Stack: global? iterproc % We must pop the resource dictionary off the dict stack % when doing the actual iteration, and restore it afterwards. exch { true .setglobal } { .LocalInstances length 0 ne { % We must do local instances, and do them first. .LocalInstances exch cvx /forall cvx 1 index cvlit currentdict end 3 .execn begin } if } ifelse Instances exch cvx /forall cvx currentdict end 2 .execn begin } bind/ResourceFileName { /GenericResourceDir getsystemparam Category .namestring concatstrings /GenericResourcePathSep getsystemparam concatstrings .genericrfn } bind % Additional entries % Unfortunately, we can't create the real Instances dictionary now,% because if someone copies the Generic category (which pp. 95-96 of the% 2nd Edition Red Book says is legitimate), they'll wind up sharing% the Instances. Instead, we have to create Instances on demand,% just like the entry in localinstancedict.% We also have to prevent anyone from creating instances of Generic itself./Instances //.emptydict /.LocalInstances { localinstancedict Category .knownget not { //.emptydict } if } bind/.GetInstance { currentglobal { Instances exch .knownget } { .LocalInstances 1 index .knownget { exch pop true } { Instances exch .knownget } ifelse } ifelse } bind/.CheckResource { true } bind/.DoLoadResource { dup vmstatus pop exch pop exch .LoadResource vmstatus pop exch pop exch sub 1 index .GetInstance not { pop dup /undefinedresource signalerror } % didn't load if dup 1 1 put 2 3 -1 roll put } bind/.LoadResource { dup .ResourceFile { exch pop currentglobal { .runresource } { true setglobal { .runresource } stopped false setglobal { stop } if } ifelse } { dup /undefinedresource signalerror } ifelse } bind/.ResourceFile { currentdict /ResourceFileName known { mark 1 index 100 string { ResourceFileName } .internalstopped { cleartomark false } { exch pop findlibfile { exch pop exch pop true } { pop false } ifelse } ifelse } { false } ifelse } bind .dicttomark/Category defineresource pop % Fill in the rest of the Category category./Category /Category findresource dup/Generic /Category findresource begin { /FindResource /ResourceForAll /ResourceStatus /UndefineResource /ResourceFileName /.ResourceFile /.LoadResource /.DoLoadResource } { dup load put dup } forallpop readonly pop end (END GENERIC) VMDEBUG % Define the fixed categories. mark % Non-Type categories with existing entries. /ColorSpaceFamily { } % These must be deferred, because optional features may add some. /Emulator mark EMULATORS { cvn } forall .packtomark /Filter { } % These must be deferred, because optional features may add some. /IODevice % Loop until the .getiodevice gets a rangecheck. errordict /rangecheck 2 copy get errordict /rangecheck { pop stop } put % pop the command mark 0 { { dup .getiodevice dup null eq { pop } { exch } ifelse 1 add } loop} .internalstopped pop pop pop .packtomark 4 1 roll put .clearerror % Type categories listed in the Red Book. /ColorRenderingType { } % These must be deferred, because optional features may add some. /FMapType { } % These must be deferred, because optional features may add some. /FontType { } % These must be deferred, because optional features may add some. /FormType { } % These must be deferred, because optional features may add some. /HalftoneType { } % These must be deferred, because optional features may add some. /ImageType { } % Deferred, optional features may add some. /PatternType { } % Deferred, optional features may add some. % Type categories added since the Red Book. /setsmoothness where { pop /ShadingType { } % Deferred, optional features may add some. } ifcounttomark 2 idiv { mark % Standard entries % We'd like to prohibit defineresource, % but because optional features may add entries, we can't. % We can at least require that the key and value match. /DefineResource { currentglobal not { /defineresource load /invalidaccess signalerror } { 2 copy ne { /defineresource load /rangecheck signalerror } { dup Instances 4 -2 roll .growput } ifelse } ifelse } bind /UndefineResource { /undefineresource load /invalidaccess signalerror } bind /FindResource { Instances 1 index .knownget { exch pop } { /findresource load /undefinedresource signalerror } ifelse } bind /ResourceStatus { Instances exch known { 0 0 true } { false } ifelse } bind /ResourceForAll /Generic /Category findresource /ResourceForAll get % Additional entries Lines 1–500 of 832. Load more
% Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000 Aladdin Enterprises. All rights reserved. % % This file is part of Aladdin Ghostscript. % % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author % or distributor accepts any responsibility for the consequences of using it, % or for whether it serves any particular purpose or works at all, unless he % or she says so in writing. Refer to the Aladdin Ghostscript Free Public % License (the "License") for full details. % % Every copy of Aladdin Ghostscript must include a copy of the License, % normally in a plain ASCII text file named PUBLIC. The License grants you % the right to copy, modify and redistribute Aladdin Ghostscript, but only % under certain conditions described in the License. Among other things, the % License requires that the copyright notice and this notice be preserved on % all copies. % $Id: gs_res.ps,v 1.2 2000/03/10 04:54:15 lpd Exp $ % Initialization file for Level 2 resource machinery. % When this is run, systemdict is still writable, % but (almost) everything defined here goes into level2dict. level2dict begin (BEGIN RESOURCES) VMDEBUG % We keep track of (global) instances with another entry in the resource % dictionary, an Instances dictionary. For categories with implicit % instances, the values in Instances are the same as the keys; % for other categories, the values are [instance status size]. % Note that the dictionary that defines a resource category is stored % in global VM. The PostScript manual says that each category must % manage global and local instances separately. However, objects in % global VM other than systemdict can't reference objects in local VM. % This means that the resource category dictionary, which would otherwise be % the obvious place to keep track of the instances, can't be used to keep % track of local instances. Instead, we define a dictionary in local VM % called localinstancedict, in which the key is the category name and % the value is the analogue of Instances for local instances. % We don't currently implement automatic resource unloading. % When and if we do, it should be hooked to the garbage collector. % However, Ed Taft of Adobe says their interpreters don't implement this % either, so we aren't going to worry about it for a while. currentglobal false setglobal systemdict begin /localinstancedict 5 dict .forcedef % localinstancedict is local, systemdict is global end true setglobal /.emptydict 0 dict readonly def setglobal % Resource category dictionaries have the following keys (those marked with % * are optional): % Standard, defined in the Red Book: % Category (name) % *InstanceType (name) % DefineResource % <key> <instance> DefineResource <instance> % UndefineResource % <key> UndefineResource - % FindResource % <key> FindResource <instance> % ResourceStatus % <key> ResourceStatus <status> <size> true % <key> ResourceStatus false % ResourceForAll % <template> <proc> <scratch> ResourceForAll - % *ResourceFileName % <key> <scratch> ResourceFileName <filename> % Additional, specific to our implementation: % Instances (dictionary) % .LocalInstances % - .LocalInstances <dict> % .GetInstance % <key> .GetInstance <instance> -true- % <key> .GetInstance -false- % .CheckResource % <key> <value> .CheckResource <key> <value> <ok> % (or may give an error if not OK) % .DoLoadResource % <key> .DoLoadResource - (may give an error) % .LoadResource % <key> .LoadResource - (may give an error) % .ResourceFile % <key> .ResourceFile <file> -true- % <key> .ResourceFile <key> -false- % All the above procedures expect that the top dictionary on the d-stack % is the resource dictionary. % Define enough of the Category category so we can define other categories. % The dictionary we're about to create will become the Category % category definition dictionary. % .findcategory and .resourceexec are only called from within the % implementation of the resource 'operators', so they doesn't have to worry % about cleaning up the stack if they fail (the interpreter's stack % protection machinery for pseudo-operators takes care of this). /.findcategory { % <name> .findcategory - % (pushes the category on the dstack) /Category findresource begin } bind def /.resourceexec { % <key> /xxxResource .resourceexec - % (also pops the category from the dstack) load exec end } bind def 15 dict begin % Standard entries /Category /Category def /InstanceType /dicttype def /DefineResource { .CheckResource { dup /Category 3 index cvlit .growput % We would like to make Category dictionaries read-only, % and we used to do that here, but we can't do it, % because we have to be able to replace the dummy, empty % Instances dictionary with the real one later. dup [ exch 0 -1 ] exch Instances 4 2 roll put } { /defineresource load /typecheck signalerror } ifelse } bind def /FindResource % (redefined below) { Instances exch get 0 get } bind def % Additional entries /Instances 30 dict def Instances /Category [currentdict 0 -1] put /.LocalInstances 0 dict def /.GetInstance { Instances exch .knownget } bind def /.CheckResource { dup gcheck currentglobal and { /DefineResource /FindResource /ResourceForAll /ResourceStatus /UndefineResource } { 2 index exch known and } forall not { /defineresource load /invalidaccess signalerror } if true } bind def Instances end begin % for the base case of findresource (END CATEGORY) VMDEBUG % Define the resource operators. We use the "stack protection" feature of % odef to make sure the stacks are restored properly on an error. % This requires that the operators not pop anything from the stack until % they have executed their logic successfully. We can't make this % work for resourceforall, because the procedure it executes mustn't see % the operands of resourceforall on the stack, but we can make it work for % the others. mark /defineresource { % <key> <instance> <category> defineresource <instance> 3 copy .findcategory currentdict /InstanceType known { dup type InstanceType ne { dup type /packedarraytype eq InstanceType /arraytype eq and not { /defineresource load /typecheck signalerror } if } if } if /DefineResource .resourceexec 4 1 roll pop pop pop } /findresource { % <key> <category> findresource <instance> 2 copy dup /Category eq { pop //Category 0 get begin } { .findcategory } ifelse /FindResource .resourceexec exch pop exch pop } /resourceforall { % <template> <proc> <scratch> <category> resourceforall - dup /Category findresource begin /ResourceForAll load % Make sure we can recover the original operands. % Stack: ...operands... proc 5 copy pop 4 packedarray count % Stack: ...operands... proc saved count 4 -1 roll pop % pop the category /stopped load 3 1 roll 3 .execn % Stack: ... stopped saved count 3 -1 roll { % The count is the original stack depth + 2. count exch 4 sub sub { exch pop } repeat aload pop stop } { pop pop } ifelse end } /resourcestatus { % <key> <category> resourcestatus <status> <size> true % <key> <category> resourcestatus false 2 copy .findcategory /ResourceStatus .resourceexec { 4 2 roll pop pop true } { pop pop false } ifelse } /undefineresource { % <key> <category> undefineresource - 2 copy .findcategory /UndefineResource .resourceexec pop pop } end % Instances of Category counttomark 2 idiv { bind odef } repeat pop % Define the system parameters used for the Generic implementation of % ResourceFileName. systemdict begin currentdict /pssystemparams known not { /pssystemparams 10 dict readonly def } if pssystemparams begin /FontResourceDir (/Resource/Font/) readonly .forcedef % pssys'params is r-o /GenericResourceDir (/Resource/) readonly .forcedef % pssys'params is r-o /GenericResourcePathSep (/) readonly .forcedef % pssys'params is r-o end end % Define the generic algorithm for computing resource file names. /.rfnstring 100 string def /.genericrfn % <key> <scratch> <prefix> .genericrfn <filename> { 3 -1 roll //.rfnstring cvs concatstrings exch copy } bind def % Define the Generic category. /Generic mark % Standard entries % We're still running in Level 1 mode, so dictionaries won't expand. % Leave room for the /Category entry. /Category null /DefineResource { .CheckResource { dup [ exch 0 -1 ] % Stack: key value instance currentglobal { false setglobal 2 index UndefineResource % remove local def if any true setglobal Instances dup //.emptydict eq { pop 3 dict /Instances 1 index def } if } { .LocalInstances dup //.emptydict eq { pop 3 dict localinstancedict Category 2 index put } if } ifelse % Stack: key value instance instancedict 3 index 2 index .growput % Now make the resource value read-only. 0 2 copy get { readonly } .internalstopped pop dup 4 1 roll put exch pop exch pop } { /defineresource load /typecheck signalerror } ifelse } bind /UndefineResource { { dup 2 index .knownget { dup 1 get 1 ge { dup 0 null put 1 2 put pop pop } { pop exch .undef } ifelse } { pop pop } ifelse } currentglobal { 2 copy Instances exch exec } if .LocalInstances exch exec } bind /FindResource { dup ResourceStatus { pop 1 gt % not in VM { .DoLoadResource } if .GetInstance pop % can't fail 0 get } { /findresource load /undefinedresource signalerror } ifelse } bind /ResourceStatus { dup .GetInstance { exch pop dup 1 get exch 2 get true } { .ResourceFile { closefile 2 -1 true } { pop false } ifelse } ifelse } bind /ResourceForAll { % **************** Doesn't present instance groups in % **************** the correct order yet. % Construct a new procedure to hold the arguments. % It must be in local VM to avoid a possible invalidaccess. .currentglobal 4 1 roll false .setglobal 3 packedarray % template, proc, scratch { exch pop % stack contains: key, {template, proc, scratch} 2 copy 0 get .stringmatch { 1 index type dup /stringtype eq exch /nametype eq or { 2 copy 2 get cvs exch 1 get 3 -1 roll pop } { 1 get } ifelse exec } { pop pop } ifelse } /exec cvx 3 packedarray % Stack: global? iterproc % We must pop the resource dictionary off the dict stack % when doing the actual iteration, and restore it afterwards. exch { true .setglobal } { .LocalInstances length 0 ne { % We must do local instances, and do them first. .LocalInstances exch cvx /forall cvx 1 index cvlit currentdict end 3 .execn begin } if } ifelse Instances exch cvx /forall cvx currentdict end 2 .execn begin } bind /ResourceFileName { /GenericResourceDir getsystemparam Category .namestring concatstrings /GenericResourcePathSep getsystemparam concatstrings .genericrfn } bind % Additional entries % Unfortunately, we can't create the real Instances dictionary now, % because if someone copies the Generic category (which pp. 95-96 of the % 2nd Edition Red Book says is legitimate), they'll wind up sharing % the Instances. Instead, we have to create Instances on demand, % just like the entry in localinstancedict. % We also have to prevent anyone from creating instances of Generic itself. /Instances //.emptydict /.LocalInstances { localinstancedict Category .knownget not { //.emptydict } if } bind /.GetInstance { currentglobal { Instances exch .knownget } { .LocalInstances 1 index .knownget { exch pop true } { Instances exch .knownget } ifelse } ifelse } bind /.CheckResource { true } bind /.DoLoadResource { dup vmstatus pop exch pop exch .LoadResource vmstatus pop exch pop exch sub 1 index .GetInstance not { pop dup /undefinedresource signalerror } % didn't load if dup 1 1 put 2 3 -1 roll put } bind /.LoadResource { dup .ResourceFile { exch pop currentglobal { .runresource } { true setglobal { .runresource } stopped false setglobal { stop } if } ifelse } { dup /undefinedresource signalerror } ifelse } bind /.ResourceFile { currentdict /ResourceFileName known { mark 1 index 100 string { ResourceFileName } .internalstopped { cleartomark false } { exch pop findlibfile { exch pop exch pop true } { pop false } ifelse } ifelse } { false } ifelse } bind .dicttomark /Category defineresource pop % Fill in the rest of the Category category. /Category /Category findresource dup /Generic /Category findresource begin { /FindResource /ResourceForAll /ResourceStatus /UndefineResource /ResourceFileName /.ResourceFile /.LoadResource /.DoLoadResource } { dup load put dup } forall pop readonly pop end (END GENERIC) VMDEBUG % Define the fixed categories. mark % Non-Type categories with existing entries. /ColorSpaceFamily { } % These must be deferred, because optional features may add some. /Emulator mark EMULATORS { cvn } forall .packtomark /Filter { } % These must be deferred, because optional features may add some. /IODevice % Loop until the .getiodevice gets a rangecheck. errordict /rangecheck 2 copy get errordict /rangecheck { pop stop } put % pop the command mark 0 { { dup .getiodevice dup null eq { pop } { exch } ifelse 1 add } loop} .internalstopped pop pop pop .packtomark 4 1 roll put .clearerror % Type categories listed in the Red Book. /ColorRenderingType { } % These must be deferred, because optional features may add some. /FMapType { } % These must be deferred, because optional features may add some. /FontType { } % These must be deferred, because optional features may add some. /FormType { } % These must be deferred, because optional features may add some. /HalftoneType { } % These must be deferred, because optional features may add some. /ImageType { } % Deferred, optional features may add some. /PatternType { } % Deferred, optional features may add some. % Type categories added since the Red Book. /setsmoothness where { pop /ShadingType { } % Deferred, optional features may add some. } if counttomark 2 idiv { mark % Standard entries % We'd like to prohibit defineresource, % but because optional features may add entries, we can't. % We can at least require that the key and value match. /DefineResource { currentglobal not { /defineresource load /invalidaccess signalerror } { 2 copy ne { /defineresource load /rangecheck signalerror } { dup Instances 4 -2 roll .growput } ifelse } ifelse } bind /UndefineResource { /undefineresource load /invalidaccess signalerror } bind /FindResource { Instances 1 index .knownget { exch pop } { /findresource load /undefinedresource signalerror } ifelse } bind /ResourceStatus { Instances exch known { 0 0 true } { false } ifelse } bind /ResourceForAll /Generic /Category findresource /ResourceForAll get % Additional entries