123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- % Copyright (C) 1997, 2000 Aladdin Enterprises. All rights reserved.
- %
- % This file is part of AFPL Ghostscript.
- %
- % AFPL 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 Free Public License (the
- % "License") for full details.
- %
- % Every copy of AFPL 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 AFPL 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_dps.ps,v 1.4 2000/09/19 18:29:11 lpd 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
|