📄 gs_lev2.ps
字号:
% Copyright (C) 1990, 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_lev2.ps $
% Initialization file for Level 2 functions.
% When this is run, systemdict is still writable,
% but (almost) everything defined here goes into level2dict.
level2dict begin
% ------ System and user parameters ------ %
% User parameters must obey save/restore, and must also be maintained
% per-context. We implement the former, and some of the latter, here
% with PostScript code. NOTE: our implementation assumes that user
% parameters change only as a result of setuserparams -- that there are
% no user parameters that are ever changed dynamically by the interpreter
% (although the interpreter may adjust the value presented to setuserparams)
%
% There are two types of user parameters: those which are actually
% maintained in the interpreter, and those which exist only at the
% PostScript level. We maintain the current state of both types in
% a read-only local dictionary named userparams, defined in systemdict.
% In a multi-context system, each context has its own copy of this
% dictionary. In addition, there is a constant dictionary named
% psuserparams whose keys are the names of user parameters that exist
% only in PostScript and whose values are (currently) arbitrary values
% of the correct datatype: setuserparams uses this for type checking.
% setuserparams updates userparams explicitly, in addition to setting
% any user parameters in the interpreter; thus we can use userparams
% to reset those parameters after a restore or a context switch.
% NOTE: the name userparams is known to the interpreter, and in fact
% the interpreter creates the userparams dictionary.
% Check parameters that are managed at the PostScript level.
% Currently we allow resetting them iff the new value is of the same type.
/.checksetparams { % <newdict> <opname> <checkdict>
% .checksetparams <newdict>
2 index {
% Stack: newdict opname checkdict key newvalue
3 copy pop .knownget
{ type 1 index type ne
{ pop pop pop load /typecheck signalerror }
if
dup type /stringtype eq
{ dup rcheck not
{ pop pop pop load /invalidaccess signalerror }
if
}
if
}
if pop pop
} forall pop pop
} .bind def % not odef, shouldn't reset stacks
% currentuser/systemparams creates and returns a dictionary in the
% current VM. The easiest way to make this work is to copy any composite
% PostScript-level parameters to global VM. Currently, the only such
% parameters are strings. In fact, we always copy string parameters,
% so that we can be sure the contents won't be changed.
/.copyparam { % <value> .copyparam <value'>
dup type /stringtype eq {
.currentglobal true .setglobal
1 index length string exch .setglobal
copy readonly
} if
} .bind def
% Some user parameters are managed entirely at the PostScript level.
% We take care of that here.
systemdict begin
/psuserparams 40 dict def
/getuserparam { % <name> getuserparam <value>
/userparams .systemvar 1 index get exch pop
} odef
% Fill in userparams (created by the interpreter) with current values.
mark .currentuserparams
counttomark 2 idiv {
userparams 3 1 roll put
} repeat pop
/.definepsuserparam { % <name> <value> .definepsuserparam -
psuserparams 3 copy pop put
userparams 3 1 roll put
} .bind def
end
/currentuserparams { % - currentuserparams <dict>
/userparams .systemvar dup length dict .copydict
} odef
/setuserparams { % <dict> setuserparams -
% Check that we will be able to set the PostScript-level
% user parameters.
/setuserparams /psuserparams .systemvar .checksetparams
% Set the C-level user params. If this succeeds, we know that
% the password check succeeded.
dup .setuserparams
% Now set the PostScript-level params.
% The interpreter may have adjusted the values of some of the
% parameters, so we have to read them back.
dup {
/userparams .systemvar 2 index known {
psuserparams 2 index known not {
pop dup .getuserparam
} if
.copyparam
/userparams .systemvar 3 1 roll .forceput % userparams is read-only
} {
pop pop
} ifelse
} forall
% A context switch might have occurred during the above loop,
% causing the interpreter-level parameters to be reset.
% Set them again to the new values. From here on, we are safe,
% since a context switch will consult userparams.
.setuserparams
} .bind odef
% Initialize user parameters managed here.
/JobName () .definepsuserparam
% Restore must restore the user parameters.
% (Since userparams is in local VM, save takes care of saving them.)
/restore { % <save> restore -
restore /userparams .systemvar .setuserparams
} .bind odef
% The pssystemparams dictionary holds some system parameters that
% are managed entirely at the PostScript level.
systemdict begin
currentdict /pssystemparams known not {
/pssystemparams 40 dict readonly def
} if
/getsystemparam { % <name> getsystemparam <value>
//pssystemparams 1 index .knownget { exch pop } { .getsystemparam } ifelse
} odef
end
/currentsystemparams { % - currentsystemparams <dict>
mark .currentsystemparams //pssystemparams { } forall .dicttomark
} odef
/setsystemparams { % <dict> setsystemparams -
% Check that we will be able to set the PostScript-level
% system parameters.
/setsystemparams //pssystemparams .checksetparams
% Set the C-level system params. If this succeeds, we know that
% the password check succeeded.
dup .setsystemparams
% Now set the PostScript-level params. We must copy local strings
% into global VM.
dup
{ //pssystemparams 2 index known
{ % Stack: key newvalue
.copyparam
//pssystemparams 3 1 roll .forceput % pssystemparams is read-only
}
{ pop pop
}
ifelse
}
forall pop
} .bind odef
% Initialize the passwords.
% NOTE: the names StartJobPassword and SystemParamsPassword are known to
% the interpreter, and must be bound to noaccess strings.
% The length of these strings must be max_password (iutil2.h) + 1.
/StartJobPassword 65 string noaccess def
/SystemParamsPassword 65 string noaccess def
% Redefine cache parameter setting to interact properly with userparams.
/setcachelimit {
mark /MaxFontItem 2 index .dicttomark setuserparams pop
} .bind odef
/setcacheparams {
% The MaxFontCache parameter is a system parameter, which we might
% not be able to set. Fortunately, this doesn't matter, because
% system parameters don't have to be synchronized between this code
% and the VM.
counttomark 1 add copy setcacheparams
currentcacheparams % mark size lower upper
3 -1 roll pop
/MinFontCompress 3 1 roll
/MaxFontItem exch
.dicttomark setuserparams
cleartomark
} .bind odef
% Add bogus user and system parameters to satisfy badly written PostScript
% programs that incorrectly assume the existence of all the parameters
% listed in Appendix C of the Red Book. Note that some of these may become
% real parameters later: code near the end of gs_init.ps takes care of
% removing any such parameters from ps{user,system}params.
psuserparams begin
/MaxFormItem 100000 def
/MaxPatternItem 20000 def
/MaxScreenItem 48000 def
/MaxUPathItem 5000 def
end
pssystemparams begin
/CurDisplayList 0 .forcedef
/CurFormCache 0 .forcedef
/CurOutlineCache 0 .forcedef
/CurPatternCache 0 .forcedef
/CurUPathCache 0 .forcedef
/CurScreenStorage 0 .forcedef
/CurSourceList 0 .forcedef
/DoPrintErrors false .forcedef
/MaxDisplayList 140000 .forcedef
/MaxFormCache 100000 .forcedef
/MaxOutlineCache 65000 .forcedef
/MaxPatternCache 100000 .forcedef
/MaxUPathCache 300000 .forcedef
/MaxScreenStorage 84000 .forcedef
/MaxSourceList 25000 .forcedef
/RamSize 4194304 .forcedef
end
% ------ Miscellaneous ------ %
(<<) cvn % - << -mark-
/mark load def
(>>) cvn % -mark- <key1> <value1> ... >> <dict>
/.dicttomark load def
/languagelevel 2 def
% When running in Level 2 mode, this interpreter is supposed to be
% compatible with Adobe version 2017.
/version (2017) readonly def
% If binary tokens are supported by this interpreter,
% set an appropriate default binary object format.
/setobjectformat where
{ pop
/RealFormat getsystemparam (IEEE) eq { 1 } { 3 } ifelse
/ByteOrder getsystemparam { 1 add } if
setobjectformat
} if
% ------ Virtual memory ------ %
/currentglobal % - currentglobal <bool>
/currentshared load def
/gcheck % <obj> gcheck <bool>
/scheck load def
/setglobal % <bool> setglobal -
/setshared load def
% We can make the global dictionaries very small, because they auto-expand.
/globaldict currentdict /shareddict .knownget not { 4 dict } if def
/GlobalFontDirectory SharedFontDirectory def
% VMReclaim and VMThreshold are user parameters.
/setvmthreshold { % <int> setvmthreshold -
mark /VMThreshold 2 index .dicttomark setuserparams pop
} odef
/vmreclaim { % <int> vmreclaim -
dup 0 gt {
.vmreclaim
} {
mark /VMReclaim 2 index .dicttomark setuserparams pop
} ifelse
} odef
-1 setvmthreshold
% ------ IODevices ------ %
/.getdevparams where {
pop /currentdevparams { % <iodevice> currentdevparams <dict>
.getdevparams .dicttomark
} odef
} if
/.putdevparams where {
pop /setdevparams { % <iodevice> <dict> setdevparams -
mark 1 index { } forall counttomark 2 add index
.putdevparams pop pop
} odef
} if
% ------ Job control ------ %
serverdict begin
% We could protect the job information better, but we aren't attempting
% (currently) to protect ourselves against maliciousness.
/.jobsave null def % top-level save object
/.jobsavelevel 0 def % save depth of job (0 if .jobsave is null,
% 1 otherwise)
/.adminjob true def % status of current unencapsulated job
end % serverdict
% Because there may be objects on the e-stack created since the job save,
% we have to clear the e-stack before doing the end-of-job restore.
% We do this by executing a 2 .stop, which is caught by the 2 .stopped
% in .runexec; we leave on the o-stack a procedure to execute aftewards.
%
%**************** The definition of startjob is not complete yet, since
% it doesn't reset stdin/stdout.
/.startnewjob { % <exit_bool> <password_level>
% .startnewjob -
serverdict /.jobsave get dup null eq { pop } { restore } ifelse
exch {
% Unencapsulated job
serverdict /.jobsave null put
serverdict /.jobsavelevel 0 put
serverdict /.adminjob 3 -1 roll 1 gt put
% The Adobe documentation doesn't say what happens to the
% graphics state stack in this case, but an experiment
% produced results suggesting that a grestoreall occurs.
grestoreall
} {
% Encapsulated job
pop
serverdict /.jobsave save put
serverdict /.jobsavelevel 1 put
.userdict /quit /stop load put
} ifelse
% Reset the interpreter state.
clear cleardictstack
initgraphics
false setglobal
} bind def
/.startjob { % <exit_bool> <password> <finish_proc>
% .startjob <ok_bool>
vmstatus pop pop serverdict /.jobsavelevel get eq
2 index .checkpassword 0 gt and {
exch .checkpassword exch count 3 roll count 3 sub { pop } repeat
cleardictstack
% Reset the e-stack back to the 2 .stopped in .runexec,
% passing the finish_proc to be executed afterwards.
2 .stop
} { % Password check failed
pop pop pop false
} ifelse
} odef
/startjob { % <exit_bool> <password> startjob <ok_bool>
{ .startnewjob true } .startjob
} odef
systemdict begin
/quit { % - quit -
//systemdict begin serverdict /.jobsave get null eq
{ end //quit }
{ /quit load /invalidaccess /signalerror load end exec }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -