You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
3.9 KiB

1 month ago
  1. % Copyright (C) 2001-2023 Artifex Software, Inc.
  2. % All Rights Reserved.
  3. %
  4. % This software is provided AS-IS with no warranty, either express or
  5. % implied.
  6. %
  7. % This software is distributed under license and may not be copied,
  8. % modified or distributed except as expressly authorized under the terms
  9. % of the license contained in the file LICENSE in this distribution.
  10. %
  11. % Refer to licensing information at http://www.artifex.com or contact
  12. % Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
  13. % CA 94129, USA, for further information.
  14. %
  15. % Postscript interface routines to DSC parser
  16. /send_orientation { % <orientation> send_orientation -
  17. % .parse_dsc_comments returns -1 for an Orientation key with an
  18. % unrecognized value.
  19. dup 0 ge {
  20. << /Orientation 2 index >> setpagedevice
  21. } if pop
  22. } .internalbind def
  23. % This dictionary contains local handlers for DSC comments.
  24. % See header in zdscpars.c for more information.
  25. % <dsc_dict> handler <dsc_dict>
  26. /DSCparseprocs mark
  27. /Orientation { dup /Orientation get send_orientation } .internalbind
  28. /PageOrientation { dup /PageOrientation .knownget { send_orientation }
  29. { dup /Orientation .knownget { send_orientation } if }
  30. ifelse } .internalbind
  31. /Page { dup /Orientation .knownget { send_orientation } if } .internalbind
  32. /NOP { } .internalbind
  33. .dicttomark readonly def
  34. % This procedure is called whenever a DSC comment is found by the interpreter
  35. /do_parse_dsc //false def
  36. /parse_dsc { % <file> <DSC string> [<prev proc>]
  37. % parse_dsc -
  38. % Run any previously installed parser.
  39. 0 get dup //null eq { pop } { 3 copy exec pop } ifelse
  40. do_parse_dsc { % Check if this parser is enabled
  41. currentglobal //true setglobal % Go to global VM, save old state
  42. 3 1 roll % Put old VM state under <file> <string>
  43. dsc_dict exch % <VM state> <file> <dict> <string>
  44. .parse_dsc_comments % <VM state> <file> <dict> <DSC name>
  45. 4 -1 roll % Get old VM state from under <file> <dict> <DSC name>
  46. setglobal % restore previous VM state
  47. //DSCparseprocs exch .knownget { % Check DSC name against local handler list
  48. exec % execute any local handler
  49. } if
  50. } if
  51. pop pop % remove file, dict
  52. } .internalbind def
  53. % Check whether the currently installed parser is the one defined in this file.
  54. /.using_parse_dsc { % - .using_parse_dsc <proc> <using?>
  55. currentuserparams /ProcessDSCComment get
  56. dup //null eq { pop {{//null} //parse_dsc exec} } if
  57. dup length 3 eq {
  58. dup dup length 1 sub get /parse_dsc load eq
  59. } {
  60. //false
  61. } ifelse
  62. } .internalbind def
  63. % Establish a .internalbinding for dsc_dict.
  64. userdict /dsc_dict //null put
  65. % - dsc_init -
  66. /dsc_init { % Initialize DSC parser
  67. currentglobal //true setglobal
  68. /dsc_dict 50 dict store % Size must be large enough for all DSC values
  69. dsc_dict .initialize_dsc_parser
  70. .using_parse_dsc {
  71. % Already using this parser.
  72. pop
  73. } {
  74. % Encapsulate the previous parser. We know it is in global VM:
  75. % allocate the new one in global VM as well.
  76. 1 array astore
  77. /parse_dsc load /exec load 3 array astore cvx readonly
  78. << /ProcessDSCComment 3 -1 roll >>
  79. setuserparams
  80. } ifelse
  81. setglobal
  82. /do_parse_dsc //true def
  83. } .internalbind def
  84. % Enable the DSC parser defined in this file.
  85. % - enable_dsc -
  86. /enable_dsc {
  87. dsc_init
  88. } .internalbind def
  89. % Disable the DSC parser defined in this file.
  90. % - disable_dsc -
  91. /disable_dsc {
  92. % There might be another parser installed: if so, restore it.
  93. % (If it has encapsulated our parser, we can't.)
  94. .using_parse_dsc {
  95. % Restore the parser we encapsulated.
  96. 0 get 0 get
  97. currentglobal //true setglobal exch
  98. << /ProcessDSCComment 3 -1 roll >>
  99. exch setglobal setuserparams
  100. } {
  101. pop
  102. } ifelse
  103. % If we couldn't restore the old parser, at least disable ours.
  104. /do_parse_dsc //false def
  105. } .internalbind def