?? gs_res.ps
字號:
% Copyright (C) 1994, 1996, 1997, 1998 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 $
% 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 memory. The PostScript manual says that each category must
% manage global and local instances separately. However, objects in
% global memory other than systemdict can't reference objects in local memory.
% 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
/.internalstopped 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
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -