ps2epsi.ps 8.5 KB

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