diff options
Diffstat (limited to 'Master/xemtex/gslib/gs_dps.ps')
-rw-r--r-- | Master/xemtex/gslib/gs_dps.ps | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/Master/xemtex/gslib/gs_dps.ps b/Master/xemtex/gslib/gs_dps.ps new file mode 100644 index 00000000000..10c7577e1cd --- /dev/null +++ b/Master/xemtex/gslib/gs_dps.ps @@ -0,0 +1,203 @@ +% Copyright (C) 1997, 2000 Aladdin Enterprises. All rights reserved. +% +% This program is free software; you can redistribute it and/or modify it +% under the terms of the GNU General Public License as published by the +% Free Software Foundation; either version 2 of the License, or (at your +% option) any later version. +% +% This program is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +% Public License for more details. +% +% You should have received a copy of the GNU General Public License along +% with this program; if not, write to the Free Software Foundation, Inc., +% 59 Temple Place, Suite 330, Boston, MA, 02111-1307. + +% $Id: gs_dps.ps,v 1.4.6.1.2.1 2003/04/12 14:02:38 giles Exp $ +% Initialization file for Display PostScript functions. + +% ------ Contexts ------ % + +% To create a context with private local VM, we use the .localfork +% operator to actually create the context, the new VM, and an empty +% userdict, and then we call the .initlocaldicts procedure to make +% local copies of the initial contents of the dictionaries in local VM. +% savedlocaldicts in systemdict is a global read-only dictionary whose +% elements are global read-only copies of these initial contents; +% we just copy its elements into local VM and install them in systemdict. +% userdict and internaldict require special handling. + +% Switching between contexts with different local VMs requires +% changing the bindings in systemdict that reference local objects. +% For this purpose, each userdict has an entry called localdicts +% which holds the local copies of the elements of savedlocaldicts, +% plus internaldict. The context switching code in the interpreter +% effectively copies this dictionary into systemdict. +% NOTE: the name localdicts is known to the interpreter. + +% Switching between contexts also requires resetting the user parameters. +% The interpreter records the value of userparams (a local dictionary +% referenced from systemdict) for each context, and uses it for this. +% See gs_lev2.ps for more details. +% NOTE: the name userparams is known to the interpreter. + +% Save copies of local dictionaries at the end of system initialization. +% Also save the initial gstate. +/.savelocalstate { + .currentglobal true .setglobal + //systemdict /savedlocaldicts mark //systemdict { + dup gcheck { + pop pop + } { + dup type /dicttype eq { + % Save a copy of this dictionary in global VM. + dup maxlength dict .copydict readonly + } { + pop pop + } ifelse + } ifelse + } forall .dicttomark readonly put + % Create localdicts for the current context. + false .setglobal + userdict /localdicts mark savedlocaldicts { + pop dup load + } forall /internaldict dup load + .dicttomark readonly put + % Save a copy of the initial gstate. + true .setglobal + //systemdict /savedinitialgstate gstate readonly put + .setglobal +} .bind def + +% Initialize local dictionaries and gstate when creating a new context. +% Note that until this completes, we are in the anomalous situation of +% having systemdict point to dictionaries that are in a non-current +% local VM. Because of this, we turn off garbage collection temporarily. +/.copylocal { % <name> <dict> .copylocal <name> <dict'> + % Copy a dictionary to the current (local) VM, + % and make it read-only if its current definition is. + dup maxlength dict .copydict + 1 index load wcheck not { readonly } if +} .bind def +% When this is called, the dictionary stack is in its initial state, +% and there is (anomalously) only one gstate on the gstate stack. +/.initlocaldicts { % - .initlocaldicts - + -2 vmreclaim + .currentglobal //systemdict begin + false .setglobal + % Since localdicts doesn't exist yet, references from + % systemdict to local objects won't get restored if + % a context switch happens in this code. Therefore, + % until localdicts is defined, we have to keep all our + % state on the operand stack. + + % Acquire userdict. + %****** WRONG IF NON-STANDARD INITIAL DSTACK ****** + countdictstack array dictstack + { dup gcheck not { exit } if pop } forall + % Create localdicts with a local copy of each dictionary, + % except for userdict and userparams, which just need + % to be filled in. + mark savedlocaldicts { + 1 index /userdict eq { + % Stack: userdict mark ... /userdict inituserdict + counttomark 1 add index .copydict + } { + 1 index /userparams eq { + % Stack: userdict mark ... /userparams inituserparams + userparams .copydict + } { + .copylocal + } ifelse + } ifelse + } forall /internaldict dup .makeinternaldict .makeoperator + .dicttomark readonly /localdicts exch put + % localdicts is now defined in userdict. + % Copy the definitions into systemdict. + localdicts { .forcedef } forall + % Set the user parameters. + userparams readonly .setuserparams + % Establish the initial gstate(s). + /savedinitialgstate .systemvar setgstate gsave + % Wrap up. + end .setglobal +} odef + +% Check whether an object is a procedure. +/.proccheck { % <obj> .proccheck <bool> + dup xcheck + exch type dup /arraytype eq exch /packedarraytype eq or and +} bind def + +% Create a context with private local VM. +% The .localfork operator does all the work, but we must ensure that +% .initlocaldicts gets called when the new context starts up. +/localfork { % <mark> <obj1> ... <objN> <proc> + % <stdin|null> <stdout|null> + % localfork <context> + .currentglobal true .setglobal 3 index + dup .proccheck not { + pop .setglobal /localfork cvx /typecheck signalerror + } if + {exec .initlocaldicts} aload pop + 3 1 roll 3 packedarray cvx + 4 1 roll 5 -1 roll pop .setglobal .localfork +} odef + +% Fork a context that shares VM. The .fork operator creates an empty +% userparams dictionary for the context, but we still need to initialize +% this dictionary when the new context starts up. +/.postfork { % - .postfork - + % Initialize the user parameters. + savedlocaldicts /userparams get userparams .copydict readonly pop +} odef +/fork { % <mark> <obj1> ... <objN> <proc> fork <context> + .currentglobal false .setglobal 1 index + dup .proccheck not { + pop .setglobal /fork cvx /typecheck signalerror + } if + {exec .postfork} aload pop + 3 1 roll 3 packedarray cvx + 3 1 roll exch pop .setglobal .fork +} odef + +% ------ Halftone phase ------ % + +/sethalftonephase { % <x> <y> sethalftonephase - + -1 2 index 2 index .setscreenphase pop pop +} odef +/currenthalftonephase { % - currenthalftonephase <x> <y> + 0 .currentscreenphase +} odef + +% ------ Device-source images ------ */ + +.imagetypes 2 /.image2 load put + +% ------ Device information ------ % + +/.deviceinfodict mark + /Colors null /GrayValues null /RedValues null /GreenValues null + /BlueValues null /ColorValues null +.dicttomark readonly def +/deviceinfo { % - deviceinfo <dict> + currentdevice //.deviceinfodict .getdeviceparams .dicttomark readonly +} odef + +% The current implementation allocates a 2-element array each time. +% Perhaps we should change this to 2 separate parameters for X and Y? +/.wtdict mark + /wtranslation null +.dicttomark readonly def +/wtranslation { % - wtranslation <x> <y> + currentdevice //.wtdict .getdeviceparams exch pop exch pop aload pop +} odef +currentdict /.wtdict .undef + +% ------ View clipping ------ % + +/rectviewclip { % <x> <y> <width> <height> rectviewclip - + % <numarray|numstring> rectviewclip - + newpath .rectappend viewclip +} odef |