gs_dps.ps 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. % Copyright (C) 1997, 2000 Aladdin Enterprises. All rights reserved.
  2. %
  3. % This software is provided AS-IS with no warranty, either express or
  4. % implied.
  5. %
  6. % This software is distributed under license and may not be copied,
  7. % modified or distributed except as expressly authorized under the terms
  8. % of the license contained in the file LICENSE in this distribution.
  9. %
  10. % For more information about licensing, please refer to
  11. % http://www.ghostscript.com/licensing/. For information on
  12. % commercial licensing, go to http://www.artifex.com/licensing/ or
  13. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  14. % San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  15. % $Id: gs_dps.ps,v 1.8 2002/11/14 17:24:00 raph Exp $
  16. % Initialization file for Display PostScript functions.
  17. % ------ Contexts ------ %
  18. % To create a context with private local VM, we use the .localfork
  19. % operator to actually create the context, the new VM, and an empty
  20. % userdict, and then we call the .initlocaldicts procedure to make
  21. % local copies of the initial contents of the dictionaries in local VM.
  22. % savedlocaldicts in systemdict is a global read-only dictionary whose
  23. % elements are global read-only copies of these initial contents;
  24. % we just copy its elements into local VM and install them in systemdict.
  25. % userdict and internaldict require special handling.
  26. % Switching between contexts with different local VMs requires
  27. % changing the bindings in systemdict that reference local objects.
  28. % For this purpose, each userdict has an entry called localdicts
  29. % which holds the local copies of the elements of savedlocaldicts,
  30. % plus internaldict. The context switching code in the interpreter
  31. % effectively copies this dictionary into systemdict.
  32. % NOTE: the name localdicts is known to the interpreter.
  33. % Switching between contexts also requires resetting the user parameters.
  34. % The interpreter records the value of userparams (a local dictionary
  35. % referenced from systemdict) for each context, and uses it for this.
  36. % See gs_lev2.ps for more details.
  37. % NOTE: the name userparams is known to the interpreter.
  38. % Save copies of local dictionaries at the end of system initialization.
  39. % Also save the initial gstate.
  40. /.savelocalstate {
  41. .currentglobal true .setglobal
  42. //systemdict /savedlocaldicts mark //systemdict {
  43. dup gcheck {
  44. pop pop
  45. } {
  46. dup type /dicttype eq {
  47. % Save a copy of this dictionary in global VM.
  48. dup maxlength dict .copydict readonly
  49. } {
  50. pop pop
  51. } ifelse
  52. } ifelse
  53. } forall .dicttomark readonly put
  54. % Create localdicts for the current context.
  55. false .setglobal
  56. userdict /localdicts mark savedlocaldicts {
  57. pop dup load
  58. } forall /internaldict dup load
  59. .dicttomark readonly put
  60. % Save a copy of the initial gstate.
  61. true .setglobal
  62. //systemdict /savedinitialgstate gstate readonly put
  63. .setglobal
  64. } .bind def
  65. % Initialize local dictionaries and gstate when creating a new context.
  66. % Note that until this completes, we are in the anomalous situation of
  67. % having systemdict point to dictionaries that are in a non-current
  68. % local VM. Because of this, we turn off garbage collection temporarily.
  69. /.copylocal { % <name> <dict> .copylocal <name> <dict'>
  70. % Copy a dictionary to the current (local) VM,
  71. % and make it read-only if its current definition is.
  72. dup maxlength dict .copydict
  73. 1 index load wcheck not { readonly } if
  74. } .bind def
  75. % When this is called, the dictionary stack is in its initial state,
  76. % and there is (anomalously) only one gstate on the gstate stack.
  77. /.initlocaldicts { % - .initlocaldicts -
  78. -2 vmreclaim
  79. .currentglobal //systemdict begin
  80. false .setglobal
  81. % Since localdicts doesn't exist yet, references from
  82. % systemdict to local objects won't get restored if
  83. % a context switch happens in this code. Therefore,
  84. % until localdicts is defined, we have to keep all our
  85. % state on the operand stack.
  86. % Acquire userdict.
  87. %****** WRONG IF NON-STANDARD INITIAL DSTACK ******
  88. countdictstack array dictstack
  89. { dup gcheck not { exit } if pop } forall
  90. % Create localdicts with a local copy of each dictionary,
  91. % except for userdict and userparams, which just need
  92. % to be filled in.
  93. mark savedlocaldicts {
  94. 1 index /userdict eq {
  95. % Stack: userdict mark ... /userdict inituserdict
  96. counttomark 1 add index .copydict
  97. } {
  98. 1 index /userparams eq {
  99. % Stack: userdict mark ... /userparams inituserparams
  100. userparams .copydict
  101. } {
  102. .copylocal
  103. } ifelse
  104. } ifelse
  105. } forall /internaldict dup .makeinternaldict .makeoperator
  106. .dicttomark readonly /localdicts exch put
  107. % localdicts is now defined in userdict.
  108. % Copy the definitions into systemdict.
  109. localdicts { .forcedef } forall
  110. % Set the user parameters.
  111. userparams readonly .setuserparams
  112. % Establish the initial gstate(s).
  113. /savedinitialgstate .systemvar setgstate gsave
  114. % Wrap up.
  115. end .setglobal
  116. } odef
  117. % Check whether an object is a procedure.
  118. /.proccheck { % <obj> .proccheck <bool>
  119. dup xcheck
  120. exch type dup /arraytype eq exch /packedarraytype eq or and
  121. } bind def
  122. % Create a context with private local VM.
  123. % The .localfork operator does all the work, but we must ensure that
  124. % .initlocaldicts gets called when the new context starts up.
  125. /localfork { % <mark> <obj1> ... <objN> <proc>
  126. % <stdin|null> <stdout|null>
  127. % localfork <context>
  128. .currentglobal true .setglobal 3 index
  129. dup .proccheck not {
  130. pop .setglobal /localfork cvx /typecheck signalerror
  131. } if
  132. {exec .initlocaldicts} aload pop
  133. 3 1 roll 3 packedarray cvx
  134. 4 1 roll 5 -1 roll pop .setglobal .localfork
  135. } odef
  136. % Fork a context that shares VM. The .fork operator creates an empty
  137. % userparams dictionary for the context, but we still need to initialize
  138. % this dictionary when the new context starts up.
  139. /.postfork { % - .postfork -
  140. % Initialize the user parameters.
  141. savedlocaldicts /userparams get userparams .copydict readonly pop
  142. } odef
  143. /fork { % <mark> <obj1> ... <objN> <proc> fork <context>
  144. .currentglobal false .setglobal 1 index
  145. dup .proccheck not {
  146. pop .setglobal /fork cvx /typecheck signalerror
  147. } if
  148. {exec .postfork} aload pop
  149. 3 1 roll 3 packedarray cvx
  150. 3 1 roll exch pop .setglobal .fork
  151. } odef
  152. % ------ Halftone phase ------ %
  153. /sethalftonephase { % <x> <y> sethalftonephase -
  154. -1 2 index 2 index .setscreenphase pop pop
  155. } odef
  156. /currenthalftonephase { % - currenthalftonephase <x> <y>
  157. 0 .currentscreenphase
  158. } odef
  159. % ------ Device-source images ------ */
  160. .imagetypes 2 /.image2 load put
  161. % ------ Device information ------ %
  162. /.deviceinfodict mark
  163. /Colors null /GrayValues null /RedValues null /GreenValues null
  164. /BlueValues null /ColorValues null
  165. .dicttomark readonly def
  166. /deviceinfo { % - deviceinfo <dict>
  167. currentdevice //.deviceinfodict .getdeviceparams .dicttomark
  168. dup begin
  169. /ColorValues .knownget {
  170. 0 le
  171. { currentdict /ColorValues undef }
  172. {
  173. % hack around devices that incorrect set GrayValues
  174. Colors 3 eq { 1 } { GrayValues } ifelse
  175. RedValues mul GreenValues mul BlueValues mul ColorValues ne
  176. { currentdict /GrayValues undef
  177. currentdict /RedValues undef
  178. currentdict /GreenValues undef
  179. currentdict /BlueValues undef
  180. } if
  181. }
  182. ifelse
  183. } if
  184. currentdict end readonly
  185. } odef
  186. % The current implementation allocates a 2-element array each time.
  187. % Perhaps we should change this to 2 separate parameters for X and Y?
  188. /.wtdict mark
  189. /wtranslation null
  190. .dicttomark readonly def
  191. /wtranslation { % - wtranslation <x> <y>
  192. currentdevice //.wtdict .getdeviceparams exch pop exch pop aload pop
  193. } odef
  194. currentdict /.wtdict .undef
  195. % ------ View clipping ------ %
  196. /rectviewclip { % <x> <y> <width> <height> rectviewclip -
  197. % <numarray|numstring> rectviewclip -
  198. newpath .rectappend viewclip
  199. } odef