henesyinit from p9fd787fda5 years agoHistory
832 lines · 24.4 KB · Text
RawDownload
%    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.