gs_dps.ps 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. % Copyright (C) 1997, 2000 Aladdin Enterprises. All rights reserved.
  2. %
  3. % This file is part of AFPL Ghostscript.
  4. %
  5. % AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or
  6. % distributor accepts any responsibility for the consequences of using it, or
  7. % for whether it serves any particular purpose or works at all, unless he or
  8. % she says so in writing. Refer to the Aladdin Free Public License (the
  9. % "License") for full details.
  10. %
  11. % Every copy of AFPL Ghostscript must include a copy of the License, normally
  12. % in a plain ASCII text file named PUBLIC. The License grants you the right
  13. % to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14. % conditions described in the License. Among other things, the License
  15. % requires that the copyright notice and this notice be preserved on all
  16. % copies.
  17. % $Id: gs_dps.ps,v 1.4 2000/09/19 18:29:11 lpd Exp $
  18. % Initialization file for Display PostScript functions.
  19. % ------ Contexts ------ %
  20. % To create a context with private local VM, we use the .localfork
  21. % operator to actually create the context, the new VM, and an empty
  22. % userdict, and then we call the .initlocaldicts procedure to make
  23. % local copies of the initial contents of the dictionaries in local VM.
  24. % savedlocaldicts in systemdict is a global read-only dictionary whose
  25. % elements are global read-only copies of these initial contents;
  26. % we just copy its elements into local VM and install them in systemdict.
  27. % userdict and internaldict require special handling.
  28. % Switching between contexts with different local VMs requires
  29. % changing the bindings in systemdict that reference local objects.
  30. % For this purpose, each userdict has an entry called localdicts
  31. % which holds the local copies of the elements of savedlocaldicts,
  32. % plus internaldict. The context switching code in the interpreter
  33. % effectively copies this dictionary into systemdict.
  34. % NOTE: the name localdicts is known to the interpreter.
  35. % Switching between contexts also requires resetting the user parameters.
  36. % The interpreter records the value of userparams (a local dictionary
  37. % referenced from systemdict) for each context, and uses it for this.
  38. % See gs_lev2.ps for more details.
  39. % NOTE: the name userparams is known to the interpreter.
  40. % Save copies of local dictionaries at the end of system initialization.
  41. % Also save the initial gstate.
  42. /.savelocalstate {
  43. .currentglobal true .setglobal
  44. //systemdict /savedlocaldicts mark //systemdict {
  45. dup gcheck {
  46. pop pop
  47. } {
  48. dup type /dicttype eq {
  49. % Save a copy of this dictionary in global VM.
  50. dup maxlength dict .copydict readonly
  51. } {
  52. pop pop
  53. } ifelse
  54. } ifelse
  55. } forall .dicttomark readonly put
  56. % Create localdicts for the current context.
  57. false .setglobal
  58. userdict /localdicts mark savedlocaldicts {
  59. pop dup load
  60. } forall /internaldict dup load
  61. .dicttomark readonly put
  62. % Save a copy of the initial gstate.
  63. true .setglobal
  64. //systemdict /savedinitialgstate gstate readonly put
  65. .setglobal
  66. } .bind def
  67. % Initialize local dictionaries and gstate when creating a new context.
  68. % Note that until this completes, we are in the anomalous situation of
  69. % having systemdict point to dictionaries that are in a non-current
  70. % local VM. Because of this, we turn off garbage collection temporarily.
  71. /.copylocal { % <name> <dict> .copylocal <name> <dict'>
  72. % Copy a dictionary to the current (local) VM,
  73. % and make it read-only if its current definition is.
  74. dup maxlength dict .copydict
  75. 1 index load wcheck not { readonly } if
  76. } .bind def
  77. % When this is called, the dictionary stack is in its initial state,
  78. % and there is (anomalously) only one gstate on the gstate stack.
  79. /.initlocaldicts { % - .initlocaldicts -
  80. -2 vmreclaim
  81. .currentglobal //systemdict begin
  82. false .setglobal
  83. % Since localdicts doesn't exist yet, references from
  84. % systemdict to local objects won't get restored if
  85. % a context switch happens in this code. Therefore,
  86. % until localdicts is defined, we have to keep all our
  87. % state on the operand stack.
  88. % Acquire userdict.
  89. %****** WRONG IF NON-STANDARD INITIAL DSTACK ******
  90. countdictstack array dictstack
  91. { dup gcheck not { exit } if pop } forall
  92. % Create localdicts with a local copy of each dictionary,
  93. % except for userdict and userparams, which just need
  94. % to be filled in.
  95. mark savedlocaldicts {
  96. 1 index /userdict eq {
  97. % Stack: userdict mark ... /userdict inituserdict
  98. counttomark 1 add index .copydict
  99. } {
  100. 1 index /userparams eq {
  101. % Stack: userdict mark ... /userparams inituserparams
  102. userparams .copydict
  103. } {
  104. .copylocal
  105. } ifelse
  106. } ifelse
  107. } forall /internaldict dup .makeinternaldict .makeoperator
  108. .dicttomark readonly /localdicts exch put
  109. % localdicts is now defined in userdict.
  110. % Copy the definitions into systemdict.
  111. localdicts { .forcedef } forall
  112. % Set the user parameters.
  113. userparams readonly .setuserparams
  114. % Establish the initial gstate(s).
  115. /savedinitialgstate .systemvar setgstate gsave
  116. % Wrap up.
  117. end .setglobal
  118. } odef
  119. % Check whether an object is a procedure.
  120. /.proccheck { % <obj> .proccheck <bool>
  121. dup xcheck
  122. exch type dup /arraytype eq exch /packedarraytype eq or and
  123. } bind def
  124. % Create a context with private local VM.
  125. % The .localfork operator does all the work, but we must ensure that
  126. % .initlocaldicts gets called when the new context starts up.
  127. /localfork { % <mark> <obj1> ... <objN> <proc>
  128. % <stdin|null> <stdout|null>
  129. % localfork <context>
  130. .currentglobal true .setglobal 3 index
  131. dup .proccheck not {
  132. pop .setglobal /localfork cvx /typecheck signalerror
  133. } if
  134. {exec .initlocaldicts} aload pop
  135. 3 1 roll 3 packedarray cvx
  136. 4 1 roll 5 -1 roll pop .setglobal .localfork
  137. } odef
  138. % Fork a context that shares VM. The .fork operator creates an empty
  139. % userparams dictionary for the context, but we still need to initialize
  140. % this dictionary when the new context starts up.
  141. /.postfork { % - .postfork -
  142. % Initialize the user parameters.
  143. savedlocaldicts /userparams get userparams .copydict readonly pop
  144. } odef
  145. /fork { % <mark> <obj1> ... <objN> <proc> fork <context>
  146. .currentglobal false .setglobal 1 index
  147. dup .proccheck not {
  148. pop .setglobal /fork cvx /typecheck signalerror
  149. } if
  150. {exec .postfork} aload pop
  151. 3 1 roll 3 packedarray cvx
  152. 3 1 roll exch pop .setglobal .fork
  153. } odef
  154. % ------ Halftone phase ------ %
  155. /sethalftonephase { % <x> <y> sethalftonephase -
  156. -1 2 index 2 index .setscreenphase pop pop
  157. } odef
  158. /currenthalftonephase { % - currenthalftonephase <x> <y>
  159. 0 .currentscreenphase
  160. } odef
  161. % ------ Device-source images ------ */
  162. .imagetypes 2 /.image2 load put
  163. % ------ Device information ------ %
  164. /.deviceinfodict mark
  165. /Colors null /GrayValues null /RedValues null /GreenValues null
  166. /BlueValues null /ColorValues null
  167. .dicttomark readonly def
  168. /deviceinfo { % - deviceinfo <dict>
  169. currentdevice //.deviceinfodict .getdeviceparams .dicttomark readonly
  170. } odef
  171. % The current implementation allocates a 2-element array each time.
  172. % Perhaps we should change this to 2 separate parameters for X and Y?
  173. /.wtdict mark
  174. /wtranslation null
  175. .dicttomark readonly def
  176. /wtranslation { % - wtranslation <x> <y>
  177. currentdevice //.wtdict .getdeviceparams exch pop exch pop aload pop
  178. } odef
  179. currentdict /.wtdict .undef
  180. % ------ View clipping ------ %
  181. /rectviewclip { % <x> <y> <width> <height> rectviewclip -
  182. % <numarray|numstring> rectviewclip -
  183. newpath .rectappend viewclip
  184. } odef