henesyinit from p9fce6d0435 years agoHistory
427 lines · 12.5 KB · Text
RawDownload
%    Copyright (C) 1994 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. % The current implementation of setpagedevice is extremely limited.% It is intended only to support a minimal set of keys that common% applications expect to be able to read and set, namely those given% as the value of .pagedevicekeys below.  In particular, it does not% support media selection or Policies.  It runs the Install procedure% at the appropriate time, but does not save the resulting CTM as the% one for initmatrix or defaultmatrix. languagelevel 1 .setlanguagelevellevel2dict begin % setpagedevice ignores all keys other than the ones below; it does not% give an error or invoke Policies for unknown keys. /.pagedevicekeys mark	{ /BeginPage /EndPage /HWResolution /ImagingBBox	  /Install /Margins /NumCopies /OutputDevice /PageSize	  /ProcessColorModel	}	{ dup } forall.dicttomark def /.pagedevicedict	% <device> .pagedevicedict <dict> { .pagedevicekeys .getdeviceparams .dicttomark } bind def % currentpagedevice just selects the page device keys from the entire% set of device parameters. /currentpagedevice { .currentpagedevice dup length 0 eq    { pop currentdevice .pagedevicedict dup .setpagedevice    }   if } bind odef /.defaultdevicename 0 .getdevice .devicename def % setpagedevice is complex, but nothing compared to its full specification! /setpagedevice {   currentpagedevice 		% Check whether we are changing OutputDevice;		% also handle the case where the current device		% is not a page device.		% Stack: <request> <current>    dup /OutputDevice .knownget    {		% Current device is a page device.      2 index /OutputDevice .knownget       {	% A specific OutputDevice was requested.	 2 copy eq	  { pop pop null }	  { exch pop }	 ifelse       }       { pop null       }      ifelse    }    {		% Current device is not a page device.		% Use the default device.      1 index /OutputDevice .knownget not { .defaultdevicename } if    }   ifelse   dup null eq    { pop }    { exch pop finddevice .pagedevicedict }   ifelse 		% Merge the current and requested dictionaries.		% Stack: <request> <orig>    dup length 2 index length add dict copy copy 		% Construct the new device, and attempt to set its attributes.		% Stack: <merged>    currentdevice .devicename 1 index /OutputDevice get eq    { currentdevice }    { 1 index /OutputDevice get finddevice }  ifelse		%**************** We should copy the device here,		%**************** but since we can't close the old device,		%**************** we don't.  This is WRONG.		% Stack: <merged> <device>	%****************copydevice    null false	% Ignore undefined keys.   mark 4 index    { 1 index /OutputDevice eq { pop pop } if    } forallDEBUG { (Putting.\n) print pstack flush } if   .putdeviceparamsDEBUG { (Result of putting.\n) print pstack flush } if   dup type /nametype eq    {		% The request failed.		% Stack: <merged> <device> <policies> <mark>		%   <name> <value> ...      counttomark 1 add 1 roll cleartomark exch pop exch pop      /setpagedevice load exch signalerror    }   if 		% The attempt succeeded.  Install the new device.		% Stack: <merged> <device> <eraseflag>DEBUG { (Installing.\n) print pstack flush } if    pop 2 .endpage    { 1 true .outputpage      (>>setpagedevice, press <return> to continue<<\n) .confirm    }   if   .setdevice pop   dup /Install .knownget { exec } if   erasepage initgraphics   .setpagedevice .beginpage  } odef %****************************************************************% The remainder of this file contains an implementation of setpagedevice% that is not ready for use yet; we just skip over it.%****************************************************************(%END) .skipeof % The implementation of setpagedevice is quite complex.  Currently,% everything but the media matching algorithm is implemented here. %**************** Need an implementation of currentpagedevice using%**************** .currentpagedevice. % Define the parameters that require special action to merge into the% combined page device dictionary.  The procedures are called as follows:%	<merged> <key> <new_value> -proc- <merged> <key> <new_value'>/.mergespecial mark  /InputAttributes   { dup null eq      { pop null      }      { 3 copy pop .knownget	 { dup null eq	    { pop dup length dict }	    { dup length 2 index length add dict copy }	   ifelse	 }	 { dup length dict	 }        ifelse copy readonly      }     ifelse   } bind  /OutputAttributes 1 index  /Policies    { 3 copy pop .knownget       { dup length 2 index length add dict copy }       { dup length dict }      ifelse copy readonly    } bind.dicttomark readonly def % Define the keys used in input attribute matching./.inputattrkeys [  /PageSize /MediaColor /MediaWeight /MediaType /InsertSheet] readonly def % Define the keys used in output attribute matching./.outputattrkeys [  /OutputType] readonly def % Define the parameters that should not be presented to the device.% The procedures are called as follows:%	<merged> <key> <value> -proc-% The procedure leaves all its operands on the stack and returns% true iff the key/value pair should be presented to .putdeviceparams./.presentspecial mark  /Name false  /OutputDevice false  /InputAttributes false  .inputattrkeys { pop { 2 index /InputAttributes get null eq } } forall  /OutputAttributes false  .outputattrkeys { pop { 2 index /OutputAttributes get null eq } } forall  /Install false  /BeginPage false  /EndPage false  /Policies false.dicttomark readonly def % Define the required attributes of all page devices.% We don't include attributes such as PageSize, which all devices% are guaranteed to supply on their own./.requiredattrs mark  /InputAttributes null  /OutputAttributes null  /Install {.callinstall} bind  /BeginPage {.callbeginpage} bind  /EndPage {.callendpage} bind  /Policies mark    /PolicyNotFound 1    /PageSize 0    /PolicyReport {pop} bind  .dicttomark readonly.dicttomark readonly def % Define access to device defaults./.defaultdevicename 0 .getdevice .devicename def/.defaultdeviceparams { finddevice null .getdeviceparams } bind def % Select media (input or output)./.selectmedia		% <orig> <request> <merged> <failed>			%   (these are retained)			%   <attrdict> <attrkeys> <mediakey> .selectmedia { 4 index 4 -1 roll 3 index .matchmedia    { 4 index 3 1 roll put pop    }    {	% Adobe's implementations have a "big hairy heuristic"	% to choose the set of keys to report as having failed the match.	% For the moment, we report any keys that are in the request	% and don't have the same value as in the original dictionary.      3 index exch undef       {	% Stack: <orig> <request> <merged> <failed> <attrkey>	 3 index 1 index .knownget	  { 5 index 2 index .knownget { ne } { pop true } ifelse }	  { true }	 ifelse		% Stack: ... <failed> <attrkey> <report>	  { 2 copy /rangecheck put }	 if pop       }      forall    }   ifelse } bind def % Apply Policies to any unprocessed failed requests.% As we process each request entry, we replace the error name% in the <failed> dictionary with the policy value,% and we remove the key from the <merged> dictionary./.applypolicies		% <merged> <failed> .applypolicies <merged'> <failed'> { 1 index /Policies get 1 index    { type /integertype eq       { pop		% already processed       }       { 2 copy .knownget not { 1 index /PolicyNotFound get } if			% Stack: <merged> <failed> <Policies> <key> <policy>	 dup 1 ne	  {	% Set errorinfo and signal a configurationerror.		% Note that we currently treat all Policy values other than 1		% the same as 0.	    pop dup 4 index exch get 2 array astore	    $error /errorinfo 3 -1 roll put	    cleartomark	    /setpagedevice load /configurationerror signalerror	  }	  {	% Ignore the failed request.	    3 index 2 index 3 -1 roll put	    3 index exch undef	  }	 ifelse       }      ifelse    }   forall pop } bind def % Try setting the device parameters from the merged request./.trysetparams		% ... <merged> <(ignored)> <device> <Policies>			%   .trysetparams { true mark 5 index dup    {			% Stack: <merged> <key> <value>      .presentspecial 2 index .knownget       { exec { 3 -1 roll } { pop pop } ifelse }       { 3 -1 roll }      ifelse    }   forall popDEBUG { (Putting.\n) print pstack flush } if   .putdeviceparamsDEBUG { (Result of putting.\n) print pstack flush } if } bind def % Finally, define setpagedevice./setpagedevice {   mark exch currentpagedevice 		% Check whether we are changing OutputDevice;		% also handle the case where the current device		% is not a page device.		% Stack: mark <request> <current>DEBUG { (Checking.\n) print pstack flush } if    dup /OutputDevice .knownget    {		% Current device is a page device.      2 index /OutputDevice .knownget       {	% A specific OutputDevice was requested.	 2 copy eq	  { pop pop null }	  { exch pop }	 ifelse       }       { pop null       }      ifelse    }    {		% Current device is not a page device.		% Use the default device.      1 index /OutputDevice .knownget not { .defaultdevicename } if    }   ifelse   dup null eq    { pop    }    { exch pop .defaultdeviceparams      counttomark 2 idiv .requiredattrs length add dict      .requiredattrs exch copy      begin counttomark 2 idiv { def } repeat pop currentdict end    }   ifelse 		% Merge the current and requested dictionaries.		% Stack: mark <request> <orig>DEBUG { (Merging.\n) print pstack flush } if    exch 1 index dup length 2 index length add dict copy   dup 2 index    {		% stack: <orig> <request> <merged> <merged> <rkey> <rvalue>      .mergespecial 2 index .knownget { exec } if      put dup    }   forall pop 		% Select input and output media.		% Stack: mark <orig> <request> <merged>DEBUG { (Selecting.\n) print pstack flush } if    0 dict	% <failed>   1 index /InputAttributes get .inputattrkeys (%MediaSource) cvn .selectmedia   1 index /OutputAttributes get .outputattrkeys (%MediaDestination) cvn .selectmedia   .applypolicies 		% Construct the new device, and attempt to set its attributes.		% Stack: mark <orig> <request> <merged> <failed>DEBUG { (Constructing.\n) print pstack flush } if    currentdevice .devicename 2 index /OutputDevice get eq    { currentdevice }    { 1 index /OutputDevice get finddevice }   ifelse		%**************** We should copy the device here,		%**************** but since we can't close the old device,		%**************** we don't.  This is WRONG.	%****************copydevice   2 index /Policies get   .trysetparams   dup type /nametype eq    {		% The request failed.		% Stack: ... <failed> <device> <Policies> <mark>		%   <name> <value> ...      counttomark 4 add -1 roll      counttomark 2 idiv { dup 4 -2 roll put } repeat      exch pop 3 1 roll		% Stack: mark ... <merged> <failed> <device> <Policies>      4 2 roll .applypolicies 4 -2 roll      .trysetparams		% shouldn't fail!      dup type /booleantype ne       { 2 { counttomark 1 add 1 roll cleartomark } repeat         /setpagedevice load exch signalerror       }      if    }   if 		% The attempt succeeded.  Install the new device.		% Stack: mark ... <merged> <failed> <device> <eraseflag>DEBUG { (Installing.\n) print pstack flush } if    pop 2 .endpage    { 1 true .outputpage      (>>setpagedevice, press <return> to continue<<\n) .confirm    }   if   .setdevice pop   1 index /Install .knownget { exec } if   erasepage initgraphics   1 index .setpagedevice .beginpage 		% Clean up, calling PolicyReport if needed.		% Stack: mark ... <merged> <failed>DEBUG { (Finishing.\n) print pstack flush } if    dup length 0 ne    { 1 index /Policies get /PolicyReport get      counttomark 1 add 2 roll cleartomark      exec    }    { cleartomark    }   ifelse  } odef %END end				% level2dict.setlanguagelevel