diff options
author | 2019-10-15 12:24:12 +0200 | |
---|---|---|
committer | 2020-08-13 11:26:55 +0200 | |
commit | e088156d5b620e5e639580dacf85c6dc13823c74 (patch) | |
tree | 57f5c025e203279944da512166c20bc0521d8ccd /Resource/Init/gs_res.ps | |
download | ghostscript-gpl-patches-e088156d5b620e5e639580dacf85c6dc13823c74.tar.gz ghostscript-gpl-patches-e088156d5b620e5e639580dacf85c6dc13823c74.tar.bz2 ghostscript-gpl-patches-e088156d5b620e5e639580dacf85c6dc13823c74.zip |
Import Ghostscript 9.50ghostscript-9.50
Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
Diffstat (limited to 'Resource/Init/gs_res.ps')
-rw-r--r-- | Resource/Init/gs_res.ps | 1195 |
1 files changed, 1195 insertions, 0 deletions
diff --git a/Resource/Init/gs_res.ps b/Resource/Init/gs_res.ps new file mode 100644 index 00000000..068514bf --- /dev/null +++ b/Resource/Init/gs_res.ps @@ -0,0 +1,1195 @@ +% Copyright (C) 2001-2019 Artifex Software, Inc. +% All Rights Reserved. +% +% This software is provided AS-IS with no warranty, either express or +% implied. +% +% This software is distributed under license and may not be copied, +% modified or distributed except as expressly authorized under the terms +% of the license contained in the file LICENSE in this distribution. +% +% Refer to licensing information at http://www.artifex.com or contact +% Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +% CA 94945, U.S.A., +1(415)492-9861, for further information. +% + +% 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 /localinstancedict 5 dict + .forceput % localinstancedict is local, systemdict is global +//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 <key> (may give an error) +% .LoadResource +% <key> .LoadResource - (may give an error) +% .ResourceFile +% <key> .ResourceFile <file> -true- +% <key> .ResourceFile <key> -false- +% .ResourceFileStatus +% <key> .ResourceFileStatus 2 <vmusage> -true- +% <key> .ResourceFileStatus -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 don'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). +% Note that all places that look up categories must use .findcategory +% so that the command in case of error will be correct rather than an +% internal invocation of findresource. +/.findcategory { % <name> .findcategory - + % (pushes the category on the dstack) + /Category .findresource begin % note: *not* findresource +} bind def + +% If an error occurs within the logic of a resource operator (after operand +% acquisition and checking), the Adobe interpreters report the operator name, +% not the operator object, as the command in $error. For this reason, and +% this reason only, all resource operators must wrap their logic code in +% /<opername> cvx { ...logic... } .errorexec + +% The Category resource signals /undefined rather than /undefinedresource, +% both when referenced implicitly (to look up the category for a general +% resource operation) and when it is accessed directly (/Category /xxx +% findresource). Because of this, all resource operators must use +% .undefinedresource rather than signalling undefinedresource directly. +/.undefinedresource { % <command> .undefinedresource - + /Category dup load eq { /undefined } { /undefinedresource } ifelse + signaloperror +} bind def + +/.resourceexec { % <key> /xxxResource .resourceexec - + % (also pops the category from the dstack) + load exec end +} bind def + +% .getvminstance treats instances on disk as undefined. +/.getvminstance { % <key> .getvminstance <instance> -true- + % <key> .getvminstance -false- + .GetInstance { + dup 1 get 2 ne { //true } { pop //false } ifelse + } { + //false + } ifelse +} bind def + +20 dict begin + + % Standard entries + +/Category /Category def +/InstanceType /dicttype def + +/DefineResource { + .CheckResource { + dup /Category 3 index cvlit .growput + dup [ exch 0 -1 ] exch + .Instances 4 2 roll put + % Make the Category dictionary read-only. We will have to + % use .forceput / .forceput later to replace the dummy, + % empty .Instances dictionary with the real one later. + readonly + }{ + /defineresource cvx /typecheck signaloperror + } ifelse +} bind executeonly odef +/FindResource % (redefined below) + { .Instances exch get 0 get + } bind executeonly 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 cvx /invalidaccess signaloperror } 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. + +% findresource is the only operator that needs to bind //Category. +% We define its contents as a separate procedure so that .findcategory +% can use it without entering another level of pseudo-operator. +/.findresource { % <key> <category> findresource <instance> + 2 copy dup /Category eq + { pop //Category 0 get begin } { //.findcategory exec } ifelse + /FindResource //.resourceexec exec exch pop exch pop +} bind +end % .Instances of Category +def +/findresource { + % See above re .errorexec. + 1 .argindex % also catch stackunderflow + dup type /stringtype eq { cvn } if % for CET 23-13-04 + 3 1 roll exch pop + dup type /nametype ne { + /findresource .systemvar /typecheck signalerror + } if + /findresource cvx //.findresource .errorexec +} bind executeonly odef + +/defineresource { % <key> <instance> <category> defineresource <instance> + 2 .argindex 2 index 2 index % catch stackunderflow + % See above re .errorexec. + /defineresource cvx { + //.findcategory exec + currentdict /InstanceType known { + dup type InstanceType ne { + dup type /packedarraytype eq InstanceType /arraytype eq and + not { /defineresource cvx /typecheck signaloperror } if + } if + } if + /DefineResource //.resourceexec exec + 4 1 roll pop pop pop + } .errorexec +} bind executeonly odef +% We must prevent resourceforall from automatically restoring the stacks, +% because we don't want the stacks restored if proc causes an error or +% executes a 'stop'. On the other hand, resourceforall is defined in the +% PLRM as an operator, so it must have type /operatortype. We hack this +% by taking advantage of the fact that the interpreter optimizes tail +% calls, so stack protection doesn't apply to the very last token of an +% operator procedure. +/resourceforall1 { % <template> <proc> <scratch> <category> resourceforall1 - + dup //.findcategory exec + /ResourceForAll load + % Stack: <template> <proc> <scratch> <category> proc + exch pop % pop the category + exec end +} .bind executeonly def +/resourceforall { % <template> <proc> <scratch> <category> resourceforall1 - + //resourceforall1 exec % see above +} .bind executeonly odef +/resourcestatus { % <key> <category> resourcestatus <status> <size> true + % <key> <category> resourcestatus false + { + 0 .argindex type /nametype ne { + % CET 23-26 wants typecheck here, not undefineresource that happens + % without the check. + /resourcestatus cvx /typecheck signalerror + } if + 2 copy //.findcategory exec /ResourceStatus //.resourceexec exec + { 4 2 roll pop pop //true } { pop pop //false } ifelse + } stopped { + % Although resourcestatus is an operator, Adobe uses executable name + % for error reporting. CET 23-26 + /resourcestatus cvx $error /errorname get signalerror + } if +} .bind executeonly odef +/undefineresource { % <key> <category> undefineresource - + 0 .argindex type /nametype ne { + /undefinedresource cvx /typecheck signaloperror + } if + 1 .argindex 1 index % catch stackunderflow + + { //.findcategory exec /UndefineResource //.resourceexec exec pop pop + } stopped { + % Although undefineresource is an operator, Adobe uses executable name + % here but uses operator for the errors above. CET 23-33 + /undefineresource cvx $error /errorname get signalerror + } if +} .bind executeonly odef + +% Define the system parameters used for the Generic implementation of +% ResourceFileName. +systemdict begin + +% - .default_resource_dir <string> +/.default_resource_dir { + /LIBPATH .systemvar { + dup .file_name_current eq { + pop + } { + (Resource) search { + exch concatstrings + exch pop + .file_name_separator concatstrings exit + } { + pop + } ifelse + } ifelse + } forall +} bind def + +% <path> <name> <string> .resource_dir_name <path> <name> <string> +/.resource_dir_name +{ systemdict 2 index .knownget { + exch pop + systemdict 1 index undef + } { + dup () ne { + .file_name_directory_separator concatstrings + } if + 2 index exch //false + .file_name_combine not { + (Error: .default_resource_dir returned ) print exch print ( that can't combine with ) print = + /.default_resource_dir cvx /configurationerror signalerror + } if + } ifelse +} bind def + +currentdict /pssystemparams known not { + /pssystemparams 10 dict readonly def +} if +pssystemparams begin + //.default_resource_dir exec + /FontResourceDir (Font) //.resource_dir_name exec + readonly currentdict 3 1 roll .forceput % pssys'params is r-o + /GenericResourceDir () //.resource_dir_name exec + readonly currentdict 3 1 roll .forceput % pssys'params is r-o + pop % .default_resource_dir + /GenericResourcePathSep + .file_name_separator readonly currentdict 3 1 roll .forceput % pssys'params is r-o + currentdict (%diskFontResourceDir) cvn (/Resource/Font/) readonly .forceput % pssys'params is r-o + currentdict (%diskGenericResourceDir) cvn (/Resource/) readonly .forceput % pssys'params is r-o +end +end + +% Check if GenericResourceDir presents in LIBPATH. + +% The value of GenericResourceDir must end with directory separator. +% We use .file_name_combine to check it. +% Comments use OpenVMS syntax, because it is the most complicated case. +(x) pssystemparams /GenericResourcePathSep get +(y) concatstrings concatstrings dup length % (x]y) l1 +pssystemparams /GenericResourceDir get dup length exch % (x]y) l1 l2 (dir) +3 index //true .file_name_combine not { + exch + (File name ) print print ( cant combine with ) print = + /GenericResourceDir cvx /configurationerror signaloperror +} if +dup length % (x]y) l1 l2 (dir.x]y) l +4 2 roll add % (x]y) (dir.x]y) l ll +ne { + (GenericResourceDir value does not end with directory separator.\n) = + /GenericResourceDir cvx /configurationerror signaloperror +} if +pop pop + +pssystemparams dup /GenericResourceDir get exch /GenericResourcePathSep get +(Init) exch (gs_init.ps) concatstrings concatstrings concatstrings +status { + pop pop pop pop +} { + (\n*** Warning: GenericResourceDir doesn't point to a valid resource directory.) = + ( the -sGenericResourceDir=... option can be used to set this.\n) = + flush +} ifelse + +% Define the generic algorithm for computing resource file names. +/.rfnstring 8192 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 + +% Implement the body of Generic resourceforall for local, global, and +% external cases. 'args' is [template proc scratch resdict]. +/.enumerateresource { % <key> [- <proc> <scratch>] .enumerateresource - + 1 index type dup /stringtype eq exch /nametype eq or { + exch 1 index 2 get cvs exch + } if + % Use .setstackprotect to prevent the stacks from being restored if + % an error occurs during execution of proc. + 1 get //false .setstackprotect exec //true .setstackprotect +} bind def +/.localresourceforall { % <key> <value> <args> .localr'forall - + exch pop + 2 copy 0 get .stringmatch { //.enumerateresource exec } { pop pop } ifelse +} bind def +/.globalresourceforall { % <key> <value> <args> .globalr'forall - + exch pop + 2 copy 0 get .stringmatch { + dup 3 get begin .LocalInstances end 2 index known not { + //.enumerateresource exec + } { + pop pop + } ifelse + } { + pop pop + } ifelse +} bind def +/.externalresourceforall { % <filename> <len> <args> .externalr'forall - + 3 1 roll 1 index length 1 index sub getinterval exch + dup 3 get begin .Instances .LocalInstances end + % Stack: key args insts localinsts + 3 index known { + pop pop pop + } { + 2 index known { pop pop } { //.enumerateresource exec } ifelse + } ifelse +} bind def + +/DefineResource dup { + .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 + % As noted above, Category dictionaries are read-only, + % so we have to use .forceput here. + currentdict /.Instances 2 index .forceput % Category dict is read-only + } executeonly if + } executeonly + { .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 exec pop + dup 4 1 roll put exch pop exch pop + } executeonly + { /defineresource cvx /typecheck signaloperror + } + ifelse +} .bind executeonly .makeoperator % executeonly to prevent access to .forceput +/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 executeonly +% Because of some badly designed code in Adobe's CID font downloader that +% makes findresource and resourcestatus deliberately inconsistent with each +% other, the default FindResource must not call ResourceStatus if there is +% an instance of the desired name already defined in VM. +/FindResource { + dup //null eq { + % CET 13-06 wants /typecheck for "null findencoding" but + % .knownget doesn't fail on null + /findresource cvx /typecheck signaloperror + } if + dup //.getvminstance exec { + exch pop 0 get + } { + dup ResourceStatus { + pop 1 gt { + .DoLoadResource //.getvminstance exec not { + /findresource cvx //.undefinedresource exec + } if 0 get + } { + .GetInstance pop 0 get + } ifelse + } { + /findresource cvx //.undefinedresource exec + } ifelse + } ifelse +} .bind executeonly +% Because of some badly designed code in Adobe's CID font downloader, the +% definition of ResourceStatus for Generic and Font must be the same (!). +% We patch around this by using an intermediate .ResourceFileStatus procedure. +/ResourceStatus { + dup .GetInstance { + exch pop dup 1 get exch 2 get //true + } { + .ResourceFileStatus + } ifelse +} .bind executeonly +/.ResourceFileStatus { + .ResourceFile { closefile 2 -1 //true } { pop //false } ifelse +} bind executeonly +/ResourceForAll { + % Construct a new procedure to hold the arguments. + % All objects constructed here must be in local VM to avoid + % a possible invalidaccess. + currentdict 4 .localvmpackedarray % [template proc scratch resdict] + % We must pop the resource dictionary off the dict stack + % when doing the actual iteration, and restore it afterwards. + .currentglobal not { + .LocalInstances length 0 ne { + % We must do local instances, and do them first. + //.localresourceforall {exec} 0 get 3 .localvmpackedarray cvx + .LocalInstances exch {forall} 0 get 1 index 0 get + currentdict end 3 .execn begin + } if + } if + % Do global instances next. + //.globalresourceforall {exec} 0 get 3 .localvmpackedarray cvx + .Instances exch cvx {forall} 0 get 1 index 0 get + currentdict end 3 .execn begin + mark % args [ + Category .namestring .file_name_separator concatstrings + 2 index 0 get % args [ (c/) (t) + 1 index length 3 1 roll % args [ l (c/) (t) + concatstrings % args [ l (c/t) + [ + //true /LIBPATH .systemvar 3 index + .generate_dir_list_templates_with_length % args (t) [ l [(pt) Lp ...] + % also add on the Resources as specified by the GenericResourceDir + //true [ currentsystemparams /GenericResourceDir get] + counttomark 1 add index .generate_dir_list_templates_with_length + ] exch pop + dup length 1 sub 0 exch 2 exch { % args [ l [] i + 2 copy get % args [ l [] i (pt) + exch 2 index exch 1 add get % args [ l [] (pt) Lp + 3 index add + exch % args [ l [] Lp (pt) + + { % args [ l [] Lp (pf) + dup length % args [ l [] Lp (pf) Lpf + 2 index sub % args [ l [] Lp (pf) Lf + 2 index exch % args [ l [] Lp (pf) Lp Lf + getinterval cvn dup % args [ l [] Lp /n /n + 5 2 roll % args [ /n /n l [] Lp + } //.rfnstring filenameforall + pop % args [ /n1 /n1 ... /nN /nN l [] + } for % args [ /n1 /n1 ... /nN /nN l [] + pop pop + .dicttomark % An easy way to exclude duplicates. % args <</n/n>> + % { + { pop } 0 get + 2 index 2 get { cvs 0 } aload pop 5 index + //.externalresourceforall {exec} 0 get + % } + 7 .localvmpackedarray cvx + 3 2 roll pop % args + { forall } 0 get + currentdict end 2 .execn begin +} .bind executeonly + +/ResourceFileName { % /in (scr) --> (p/c/n) + exch //.rfnstring cvs % (scr) (n) + /GenericResourcePathSep getsystemparam exch % (scr) (/) (n) + Category .namestring % (scr) (/) (n) (c) + 3 1 roll % (scr) (c) (/) (n) + concatstrings concatstrings % (scr) (c/n) + /GenericResourceDir getsystemparam 1 index % (scr) (c/n) (p/) (c/n) + concatstrings % (scr) (c/n) (p/c/n) + dup status { + pop pop pop pop exch pop % (scr) (p/c/n) + } { + exch + .libfile + {//true} + { + pop dup .libfile + {//true} + {//false} + ifelse + } ifelse + + { + dup .filename pop + exch closefile + exch pop + } + {pop} + ifelse + } ifelse + exch copy % (p/c/n) +} .bind executeonly + + % 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 +/.vmused { + % - .vmused <usedvalue> + % usedvalue = vmstatus in global + vmstatus in local. + 0 2 { + .currentglobal not .setglobal + vmstatus pop exch pop add + } repeat +} bind executeonly odef +/.DoLoadResource { + % .LoadResource may push entries on the operand stack. + % It is an undocumented feature of Adobe implementations, + % which we must match for the sake of some badly written + % font downloading code, that such entries are popped + % automatically. + count 1 index cvlit //.vmused + % Stack: key count litkey memused + {.LoadResource} 4 1 roll 4 .execn + % Stack: ... count key memused + //.vmused exch sub + 1 index //.getvminstance exec not { + pop dup //.undefinedresource exec % didn't load + } if + dup 1 1 put + 2 3 -1 roll put + % Stack: ... count key + exch count 1 sub exch sub {exch pop} repeat +} bind +/.LoadResource + { dup .ResourceFile + { exch pop currentglobal + { //.runresource exec } + { //true setglobal { //.runresource exec } stopped //false setglobal { stop } if } + ifelse + } + { dup //.undefinedresource exec + } + ifelse + } bind +/.ResourceFile + { + Category //.rfnstring cvs length % key l + dup //.rfnstring dup length 2 index sub % key l l (buf) L-l + 3 2 roll exch getinterval % key l () + .file_name_directory_separator exch copy length add % key l1 + dup //.rfnstring dup length 2 index sub % key l1 l1 (buf) L-l + 3 2 roll exch getinterval % key l1 () + 2 index exch cvs length add % key l2 + //.rfnstring exch 0 exch getinterval % key (relative_path) + .libfile { + exch pop //true + } { + pop + currentdict /ResourceFileName known { + mark 1 index //.rfnstring { ResourceFileName } //.internalstopped exec { + cleartomark //false + } { + (r) { file } //.internalstopped exec { + cleartomark //false + } { + exch pop exch pop //true + } ifelse + } ifelse + } { + pop //false + } ifelse + } 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 /.ResourceFileStatus + /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 { <00> search { exch pop cvn exch }{ cvn exit } ifelse } .bind loop //.packtomark exec + /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 exec + pop pop pop //.packtomark exec + 4 1 roll put + //.clearerror exec + % 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 cvx /invalidaccess signaloperror } + { 2 copy ne + { /defineresource cvx /rangecheck signaloperror } + { dup .Instances 4 -2 roll .growput } + ifelse + } + ifelse + } bind executeonly + /UndefineResource + { /undefineresource cvx /invalidaccess signaloperror } bind executeonly + /FindResource + { .Instances 1 index .knownget + { exch pop } + { /findresource cvx //.undefinedresource exec } + ifelse + } bind executeonly + /ResourceStatus + { .Instances exch known { 0 0 //true } { //false } ifelse } bind executeonly + /ResourceForAll + /Generic //.findcategory exec /ResourceForAll load end + + % Additional entries + + counttomark 2 add -1 roll + dup length dict dup begin exch { dup def } forall end + % We'd like to make the .Instances readonly here, + % but because optional features may add entries, we can't. + /.Instances exch + /.LocalInstances % used by ResourceForAll + 0 dict def + + .dicttomark /Category defineresource pop + } repeat pop + +(END FIXED) VMDEBUG + +% Define the other built-in categories. + +/.definecategory % <name> -mark- <key1> ... <valuen> .definecategory - + { counttomark 2 idiv 2 add % .Instances, Category + /Generic /Category findresource dup maxlength 3 -1 roll add + dict .copydict begin + counttomark 2 idiv { def } repeat pop % pop the mark + currentdict end /Category defineresource pop + } bind def + +/ColorRendering mark /InstanceType /dicttype .definecategory +% ColorSpace is defined below +% Encoding is defined below +% Font is defined below +/Form mark /InstanceType /dicttype .definecategory +/Halftone mark /InstanceType /dicttype .definecategory +/Pattern mark /InstanceType /dicttype .definecategory +/ProcSet mark /InstanceType /dicttype .definecategory +% Added since the Red Book: +/ControlLanguage mark /InstanceType /dicttype .definecategory +/HWOptions mark /InstanceType /dicttype .definecategory +/Localization mark /InstanceType /dicttype .definecategory +/PDL mark /InstanceType /dicttype .definecategory +% CIDFont, CIDMap, and CMap are defined in gs_cidfn.ps +% FontSet is defined in gs_cff.ps +% IdiomSet is defined in gs_ll3.ps +% InkParams and TrapParams are defined in gs_trap.ps + +(END MISC) VMDEBUG + +% Define the OutputDevice category. +/OutputDevice mark +/InstanceType /dicttype +/.Instances mark +%% devicedict is not created yet so here we employ a technique similar to +%% that used to create it, in order to get the device names. We run a loop +%% executing .getdevice with incremental numbers until we get an error. +%% The devicedict creation only stops on a rangecheck, we stop on any error. +%% We need to use .internalstopped, not stopped or we get an invalidacces +%% later in this file. Instances of /OutputDevice are dictionaries, and the +%% only required key is a /PageSize. The array of 4 numbers are minimum to +%% maximum and are matches for the Adobe Acrobat Distiller values. +0 +{ + {dup .getdevice .devicename cvn 1 dict dup /PageSize [1 1 14400 14400] put [exch readonly 0 -1] 3 -1 roll 1 add} loop +} //.internalstopped exec pop +%% Remove the count, and the duplicate, from the stack +pop pop +.dicttomark +.definecategory + +% Define the ColorSpace category. + +/.defaultcsnames mark + /DefaultGray 0 + /DefaultRGB 1 + /DefaultCMYK 2 +.dicttomark readonly def + +% The "hooks" are no-ops here, redefined in LL3. +/.definedefaultcs { % <index> <value> .definedefaultcs - + pop pop +} bind def +/.undefinedefaultcs { % <index> .undefinedefaultcs - + pop +} bind def + +/ColorSpace mark + +/InstanceType /arraytype + +% We keep track of whether there are any local definitions for any of +% the Default keys. This information must get saved and restored in +% parallel with the local instance dictionary, so it must be stored in +% local VM. +userdict /.localcsdefaults //false put + +/DefineResource { + 2 copy /Generic /Category findresource /DefineResource get exec + exch pop + exch //.defaultcsnames exch .knownget { + 1 index //.definedefaultcs exec + currentglobal not { .userdict /.localcsdefaults //true put } if + } if +} bind executeonly + +/UndefineResource { + dup /Generic /Category findresource /UndefineResource get exec + //.defaultcsnames 1 index .knownget { + % Stack: resname index + currentglobal { + //.undefinedefaultcs exec pop + } { + % We removed the local definition, but there might be a global one. + exch .GetInstance { + 0 get //.definedefaultcs exec + } { + //.undefinedefaultcs exec + } ifelse + % Recompute .localcsdefaults by scanning. This is rarely needed. + .userdict /.localcsdefaults //false //.defaultcsnames { + pop .LocalInstances exch known { pop //true exit } if + } forall put + } ifelse + } { + pop + } ifelse +} bind executeonly + +.definecategory % ColorSpace + +% Define the Encoding category. + +/Encoding mark + +/InstanceType /arraytype + +% Handle already-registered encodings, including lazily loaded encodings +% that aren't loaded yet. + +/.Instances mark + EncodingDirectory + { dup length 256 eq { [ exch readonly 0 -1 ] } { pop [//null 2 -1] } ifelse + } forall +.dicttomark + +/.ResourceFileDict mark + EncodingDirectory + { dup length 256 eq { pop pop } { 0 get } ifelse + } forall +.dicttomark + +/ResourceFileName + { .ResourceFileDict 2 index .knownget + { exch copy exch pop } + { /Generic /Category findresource /ResourceFileName get exec } + ifelse + } bind executeonly + +.definecategory % Encoding + +% Make placeholders in level2dict for the redefined Encoding operators, +% so that they will be swapped properly when we switch language levels. + +/.findencoding /.findencoding load def +/findencoding /findencoding load def +/.defineencoding /.defineencoding load def + +(END ENCODING) VMDEBUG + +% Define the Font category. + +/.fontstatusaux { % <fontname> .fontstatusaux <fontname> <found> + { % Create a loop context just so we can exit it early. + % Check Fontmap. + Fontmap 1 index .knownget + { //true } + { .nativeFontmap 1 index .knownget } ifelse + + { + { + dup type /nametype eq { + .fontstatus { pop //null exit } if + } { + dup type /dicttype eq {/Path .knownget pop} if + dup type /stringtype eq { + findlibfile { closefile pop //null exit } if pop + } { + % Procedure, assume success. + pop //null exit + } ifelse + } ifelse + } forall dup //null eq { pop //true exit } if + } if + + + dup / eq { //false exit } if % / throws an error from findlibfile + % Convert names to strings; give up on other types. + dup type /nametype eq { .namestring } if + dup type /stringtype ne { //false exit } if + % Check the resource directory. + dup //.fonttempstring /FontResourceDir getsystemparam .genericrfn + status { + pop pop pop pop //true exit + } if + % Check for a file on the search path with the same name + % as the font. + findlibfile { closefile //true exit } if + % Scan a FONTPATH directory and try again. + //.scannextfontdir exec not { //false exit } if + } loop +} bind def + +/.fontstatus { % <fontname> .fontstatus <fontname> <found> + //.fontstatusaux exec + { //true } + { + .buildnativefontmap + { //.fontstatusaux exec } + { //false } ifelse + } ifelse +} bind executeonly def +currentdict /.fontstatusaux .undef + +/Font mark + +/InstanceType /dicttype + +/DefineResource + { 2 copy //definefont exch pop + /Generic /Category findresource /DefineResource get exec + } bind executeonly +/UndefineResource + { dup //undefinefont + /Generic /Category findresource /UndefineResource get exec + } bind executeonly +/FindResource { + dup //.getvminstance exec { + exch pop 0 get + } { + dup ResourceStatus { + pop 1 gt { .loadfontresource } { .GetInstance pop 0 get } ifelse + } { + .loadfontresource + } ifelse + } ifelse +} bind executeonly +/ResourceForAll { + { //.scannextfontdir exec not { exit } if } loop + /Generic /Category findresource /ResourceForAll get exec +} .bind executeonly +/.ResourceFileStatus { + .fontstatus { pop 2 -1 //true } { pop //false } ifelse +} bind executeonly + +/.loadfontresource { + dup //.vmused exch + % Hack: rebind .currentresourcefile so that all calls of + % definefont will know these are built-in fonts. + currentfile {pop //findfont exec} .execasresource % (findfont is a procedure) + exch //.vmused exch sub + % stack: name font vmused + % findfont has the prerogative of not calling definefont + % in certain obscure cases of font substitution. + 2 index //.getvminstance exec { + dup 1 1 put + 2 3 -1 roll put + } { + pop + } ifelse exch pop +} bind + +/.Instances FontDirectory length 2 mul dict + +.definecategory % Font + +% Redefine font "operators". +/.definefontmap + { /Font /Category findresource /.Instances get + dup 3 index known + { pop + } + { 2 index + % Make sure we create the array in global VM. + .currentglobal //true .setglobal + [//null 2 -1] exch .setglobal + .growput + } + ifelse + //.definefontmap exec + } bind def + +% Make sure the old definitions are still in systemdict so that +% they will get bound properly. +% NOTE: Mystery code... I can't just delete this, but don't understand why. +% Instead we will undef these three operators in gs_init.ps after all the initialization is done. + systemdict begin + /.origdefinefont /definefont load def + /.origundefinefont /undefinefont load def + /.origfindfont /findfont load def +end +/definefont { + { /Font defineresource } stopped { + /definefont cvx $error /errorname get signalerror + } if +} bind executeonly odef +/undefinefont { + /Font undefineresource +} bind executeonly odef +% The Red Book requires that findfont be a procedure, not an operator, +% but it still needs to restore the stacks reliably if it fails. +/.findfontop { + { /Font findresource } stopped { + pop /findfont $error /errorname get signalerror + } if +} bind executeonly odef +/findfont { + .findfontop +} bind executeonly def % Must be a procedure, not an operator + +% Remove initialization utilities. +currentdict /.definecategory .undef +currentdict /.emptydict .undef + +end % level2dict + +% Convert deferred resources after we finally switch to Level 2. + +/.fixresources { + % Encoding resources + EncodingDirectory + { dup length 256 eq + { /Encoding defineresource pop } + { pop pop } + ifelse + } forall + /.findencoding { + { /Encoding findresource } stopped { + pop /findencoding $error /errorname get signalerror + } if + } bind def + /findencoding /.findencoding load def % must be a procedure + /.defineencoding { /Encoding defineresource pop } bind def + % ColorRendering resources and ProcSet + systemdict /ColorRendering .knownget { + /ColorRendering exch /ProcSet defineresource pop + systemdict /ColorRendering undef + /DefaultColorRendering currentcolorrendering /ColorRendering defineresource pop + } if + % ColorSpace resources + systemdict /CIEsRGB .knownget { + /sRGB exch /ColorSpace defineresource pop + systemdict /CIEsRGB undef + } if + systemdict /CIEsRGBICC .knownget { + /sRGBICC exch /ColorSpace defineresource pop + systemdict /CIEsRGBICC undef + } if + systemdict /CIEsGRAYICC .knownget { + /sGrayICC exch /ColorSpace defineresource pop + systemdict /CIEsGRAYICC undef + } if + systemdict /CIEesRGBICC .knownget { + /esRGBICC exch /ColorSpace defineresource pop + systemdict /CIEesRGBICC undef + } if + systemdict /CIErommRGBICC .knownget { + /rommRGBICC exch /ColorSpace defineresource pop + systemdict /CIErommRGBICC undef + } if + % ColorSpaceFamily resources + colorspacedict { pop dup /ColorSpaceFamily defineresource pop } forall + % Filter resources + filterdict { pop dup /Filter defineresource pop } forall + % FontType and FMapType resources + buildfontdict { pop dup /FontType defineresource pop } forall + mark + buildfontdict 0 known { 2 3 4 5 6 7 8 } if + buildfontdict 9 known { 9 } if + counttomark { dup /FMapType defineresource pop } repeat pop + % FormType resources + .formtypes { pop dup /FormType defineresource pop } forall + % HalftoneType resources + .halftonetypes { pop dup /HalftoneType defineresource pop } forall + % ColorRenderingType resources + .colorrenderingtypes {pop dup /ColorRenderingType defineresource pop} forall + % ImageType resources + .imagetypes { pop dup /ImageType defineresource pop } forall + % PatternType resources + .patterntypes { pop dup /PatternType defineresource pop } forall + % Make the fixed resource categories immutable. + /.shadingtypes where { + pop .shadingtypes { pop dup /ShadingType defineresource pop } forall + } if + [ /ColorSpaceFamily /Emulator /Filter /IODevice /ColorRenderingType + /FMapType /FontType /FormType /HalftoneType /ImageType /PatternType + /.shadingtypes where { pop /ShadingType } if + ] { + /Category findresource + dup /.Instances get readonly pop + .LocalInstances readonly pop + readonly pop + } forall + % clean up + systemdict /.fixresources undef +} bind def + +%% Replace 1 (gs_resmp.ps) +(gs_resmp.ps) dup runlibfile VMDEBUG + +[ + /.default_resource_dir + /.resource_dir_name + /.fonttempstring /.scannextfontdir % from gs_fonts.ps +] systemdict .undefinternalnames + +[ + /.definedefaultcs + /.undefinedefaultcs + /.defaultcsnames + /.enumerateresource + /.externalresourceforall + /.getvminstance + /.globalresourceforall + /.localresourceforall + /resourceforall1 + /.resourceexec + /.undefinedresource + /.vmused +] dup level2dict .undefinternalnames +systemdict .undefinternalnames |