ps2epsi.ps 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. % Copyright (C) 1990, 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: ps2epsi.ps,v 1.10 2003/05/07 16:37:17 ray Exp $
  16. % Convert an arbitrary PostScript file to an EPSI file.
  17. %
  18. % Please do not contact these users if you have questions. They no longer
  19. % have the time, interest, or current expertise to keep this code working.
  20. % If you find bugs, please send proposed fixes to bug-gs@ghostscript.com.
  21. %
  22. % Bug fix 2002-04-20 by rayjj: Bounding box was incorrect since it depended
  23. % on the dither pattern and gray shade at the boundary. Changed to use
  24. % 8-bit grayscale preview image to allow correct bounding box (at the
  25. % expense of a 8x larger preview image). Also moved .setsafe until after
  26. % the device and file operations are complete (but still before the input
  27. % file is processed.
  28. % Bug fix 2000-04-11 by lpd: if a font didn't have a FontName (which is the
  29. % case for bitmap fonts produced by recent versions of dvips), setfont
  30. % caused an error.
  31. % Bug fix 8/21/99 by lpd: many of the margin and width computations were
  32. % wrong (off by 1). The code only "worked" because the bugs were
  33. % (mostly) in conservative directions.
  34. % Modified 3/17/98 by lpd to make it possible to run this file without
  35. % running the ps2epsi script first, for debugging.
  36. % Bug fix 9/29/97 by lpd <ghost@aladdin.com>: if the page size wasn't an
  37. % exact multiple of 8 bits, an incorrect bounding box (or a rangecheck
  38. % error) could occur.
  39. % Patched 7/26/95 by
  40. % Greg P. Kochanski <gpk@bell-labs.com>
  41. % to add many new DSC comments and make the comments conforming.
  42. % Original version contributed by
  43. % George Cameron <george@bio-medical-physics.aberdeen.ac.uk>
  44. %
  45. % Initialize, and redefine copypage and showpage.
  46. % ps2edict is normally defined in the pre-loaded code created by the
  47. % ps2epsi script.
  48. /ps2edict where { pop } { /ps2edict 25 dict def } ifelse
  49. ps2edict begin
  50. % The main procedure
  51. /ps2epsi
  52. { % Open the file
  53. outfile (w) file /epsifile exch def
  54. % Get the device parameters
  55. currentdevice getdeviceprops .dicttomark
  56. /HWSize get aload pop
  57. /devheight exch def
  58. /devwidth exch def
  59. matrix defaultmatrix
  60. /devmatrix exch def
  61. % Make a corresponding 8-bit deep memory device
  62. devmatrix devwidth devheight
  63. 256 string 0 1 255 { 1 index exch dup 255 exch sub put } for
  64. makeimagedevice
  65. /arraydevice exch def
  66. arraydevice
  67. % Turn on anti-aliasing
  68. mark /TextAlphaBits 4 /GraphicsAlphaBits 4 6 -1 roll
  69. putdeviceprops
  70. setdevice % (does an erasepage)
  71. /rowwidth devwidth def
  72. /row rowwidth string def
  73. /zerorow rowwidth string def % all zero
  74. % Replace the definition of showpage
  75. userdict /showpage { ps2edict begin epsipage end } bind put
  76. userdict /setfont { ps2edict begin epsisetfont end } bind put
  77. //systemdict /.setsafe known { .setsafe } if
  78. } bind def
  79. /epsifontdict 100 dict def
  80. /epsisetfont
  81. {
  82. % code here keeps a list of font names in dictionary epsifontdict
  83. /tmpfont exch def
  84. tmpfont /FontName known {
  85. /tmpfontname tmpfont /FontName get def
  86. epsifontdict tmpfontname known not { epsifontdict tmpfontname 0 put } if
  87. epsifontdict tmpfontname 2 copy get 1 add put
  88. } if
  89. tmpfont setfont
  90. } bind def
  91. % Get a scan line from the memory device, zeroing any bits beyond
  92. % the device width.
  93. /getscanline { % <device> <y> <string> getscanline <string>
  94. dup 4 1 roll copyscanlines pop
  95. 16#ff00 devwidth 7 and neg bitshift 255 and
  96. dup 0 ne {
  97. 1 index dup length 1 sub 2 copy get 4 -1 roll and put
  98. } {
  99. pop
  100. } ifelse
  101. } bind def
  102. /margintest { % <y-start> <step> <y-limit> margintest <y-non-blank>
  103. % <y-start> <step> <y-limit> margintest -
  104. { dup arraydevice exch row getscanline
  105. zerorow ne { exit } if pop
  106. } for
  107. } bind def
  108. /epsiNameStr 200 string def
  109. /epsiNpages 0 def
  110. /epsiNpageStr 20 string def
  111. /epsipage
  112. {
  113. /epsiNpages epsiNpages 1 add def
  114. /loopcount devheight 1 sub def
  115. % Find top margin -- minimum Y of non-blank scan line.
  116. -1 0 1 loopcount margintest
  117. dup -1 eq { (blank page!!\n) print quit }{ exch pop } ifelse
  118. /tm exch def
  119. % Find bottom margin -- maximum Y of non-blank scan line.
  120. loopcount -1 0 margintest
  121. /bm exch def
  122. % Initialise limit variables
  123. /loopcount rowwidth 1 sub def
  124. /lm loopcount def
  125. /rm 0 def
  126. % Find left and right boundaries of image
  127. tm 1 bm
  128. { % Get more data
  129. arraydevice exch row getscanline pop
  130. % Scan from left to find first non-zero element
  131. % We save first the element, then the index
  132. -1 0 1 loopcount
  133. { dup row exch get 0 ne { exch pop exit }{ pop } ifelse
  134. } for
  135. % If we found -1, row is blank ..
  136. dup -1 ne
  137. { % Find the leftmost index
  138. dup lm lt
  139. % If the new index is less, we save index and element
  140. { /lm exch def } { pop } ifelse
  141. % Now find the rightmost index
  142. loopcount -1 0
  143. { dup row exch get 0 ne { exit }{ pop } ifelse
  144. } for
  145. dup rm gt
  146. % If the new index is greater, we save index and element
  147. { /rm exch def } { pop } ifelse
  148. } if
  149. } for
  150. % Calculate the bounding box values.
  151. % Note that these must be corrected to produce closed-open intervals.
  152. /llx lm def
  153. /lly devheight bm sub 1 sub def
  154. /urx rm 1 add def
  155. /ury devheight tm sub def
  156. % Write out the magic string and bounding box information
  157. epsifile (%!PS-Adobe-2.0 EPSF-1.2\n) writestring
  158. /epsititle where { pop epsifile epsititle writestring } if
  159. /epsicreator where { pop epsifile epsicreator writestring } if
  160. /epsicrdt where { pop epsifile epsicrdt writestring } if
  161. /epsifor where { pop epsifile epsifor writestring } if
  162. epsifile flushfile
  163. % Write out the page count:
  164. epsifile (%%Pages: ) writestring
  165. epsifile epsiNpages epsiNpageStr cvs writestring
  166. epsifile (\n) writestring
  167. epsifile flushfile
  168. % Write out the list of used fonts:
  169. epsifile (%%DocumentFonts:) writestring
  170. epsifontdict {
  171. epsifile ( ) writestring
  172. pop epsiNameStr cvs epsifile exch writestring
  173. } forall
  174. epsifile (\n) writestring
  175. epsifile flushfile
  176. epsifile (%%BoundingBox: ) writestring
  177. epsifile llx write==only epsifile ( ) writestring
  178. epsifile lly write==only epsifile ( ) writestring
  179. epsifile urx write==only epsifile ( ) writestring
  180. epsifile ury write==
  181. % Define character and bit widths for the output line buffer:
  182. /cwidth rm lm sub 1 add def
  183. /out cwidth string def
  184. epsifile (%%EndComments\n\n) writestring
  185. epsifile (%%BeginProlog\n) writestring
  186. epsifile (%%BeginPreview: ) writestring
  187. epsifile cwidth write==only epsifile ( ) writestring
  188. epsifile bm tm sub 1 add write==only epsifile ( 8 ) writestring
  189. epsifile bm tm sub 1 add
  190. cwidth 39 add 40 idiv mul write==
  191. epsifile flushfile
  192. gsave
  193. tm 1 bm
  194. { % Get a scan line interval from the array device
  195. arraydevice exch row copyscanlines lm cwidth getinterval
  196. % Write out the hex data as 40 bytes per line (82 chars)
  197. 0 40 cwidth
  198. { epsifile (% ) writestring
  199. epsifile exch 2 index exch
  200. dup cwidth exch sub 40 .min getinterval writehexstring
  201. epsifile (\n) writestring
  202. } for
  203. pop
  204. } for
  205. epsifile (%%EndImage\n) writestring
  206. epsifile (%%EndPreview\n) writestring
  207. epsifile flushfile
  208. grestore
  209. erasepage initgraphics
  210. DonePage 0 1 put
  211. } bind def
  212. (outfile) getenv
  213. { /outfile exch def
  214. ps2epsi
  215. /DonePage 1 string def
  216. (%stdin) (r) file cvx execute0
  217. DonePage 0 get 0 eq { showpage } if
  218. } if
  219. end
  220. quit