1 % Copyright (C) 1989, 1996, 2002 Aladdin Enterprises. All rights reserved.
3 % This software is provided AS-IS with no warranty, either express or
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.
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.
16 % $Id: gs_epsf.ps,v 1.15 2005/08/30 23:26:49 alexcher Exp $
17 % Allow the interpreter to encapsulate EPS files, to recognize MS-DOS
18 % EPSF file headers, and skip to the PostScript section of the file.
20 % Encapsulate EPS files and optionally resize page or rescale image.
21 % To display an EPS file cropped to the bounding box:
22 % gs -dEPSCrop file.eps
23 % To display an EPS file scaled to fit the page:
24 % gs -dEPSFitPage file.eps
25 % To display a file without EPS encapsulation:
28 % When starting to process an EPS file, state is 0.
29 % After %%BoundingBox processed, state is 1 if OK or 2 if cropped.
30 % After %%HiResBoundingBox processed, state is 3 if OK or 4 if cropped.
31 % After %%EndComments processed, state is 5.
32 /EPSBoundingBoxState 5 def
33 /EPSBoundingBoxSetState {
34 //systemdict /EPSBoundingBoxState 3 -1 roll .forceput
35 } .bind odef % .forceput must be bound and hidden
37 % Parse 4 numbers for a bounding box
38 /EPSBoundingBoxParse { % (llx lly urx ury) -- llx lly urx ury true OR false
40 token {exch token {exch token {exch token {exch pop} if} if} if} if
43 5 -1 roll pop % remove mark
50 % Rescale and translate to fit the BoundingBox on the page
51 /EPSBoundingBoxFitPage { % llx lly urx ury --
52 EPSDEBUG { (gs_epsf.ps: Rescaling EPS to fit page\n) print flush } if
53 clippath pathbbox newpath
54 % translate to new origin at lower left of clippath
55 3 index 3 index translate
56 % calculate scale to fit smaller of width or height
57 exch 4 -1 roll sub 3 1 roll exch sub
58 4 2 roll 5 index 5 index 4 2 roll
59 exch 4 -1 roll sub 3 1 roll exch sub
61 exch 4 -1 roll div 3 1 roll exch div
62 1 index 1 index lt {pop}{exch pop} ifelse
64 % translate to EPS -llx,-lly
65 exch neg exch neg translate
68 % Crop the page to the BoundingBox
69 /EPSBoundingBoxCrop { % llx lly urx ury --
71 (gs_epsf.ps: Setting pagesize from EPS bounding box\n) print flush
73 exch 3 index sub exch 2 index sub % stack: llx lly urx-llx ury-lly
74 << /PageSize [ 5 -2 roll ] >> setpagedevice
75 neg exch neg exch translate
79 /EPSBoundingBoxProcess { % (llx lly urx ury) state --
80 //systemdict /EPSBoundingBoxState get 1 index lt {
81 exch EPSBoundingBoxParse
83 //systemdict /EPSCrop known {
86 //systemdict /EPSFitPage known {
89 % Warn if some of the EPS file will be clipped
90 clippath pathbbox newpath
92 5 -1 roll lt { 6 { pop } repeat true exit } if
93 4 -1 roll lt { 4 { pop } repeat true exit } if
94 3 -1 roll gt { 2 { pop } repeat true exit } if
95 exch gt { true exit } if
98 QUIET not and /EPSBoundingBoxState .systemvar 1 and 1 eq and {
99 (\n **** Warning: Some of the BoundingBox for the EPS file will be clipped.) =
100 ( Use -dEPSCrop or -dEPSFitPage to avoid clipping.\n) =
106 EPSBoundingBoxSetState
115 /ProcessEPSComment { % file comment -- file comment
116 //systemdict /EPSBoundingBoxState get 3 lt {
118 (%%EndComments) anchorsearch {
120 % ignore any following bounding boxes
121 5 EPSBoundingBoxSetState
123 (%%BoundingBox:) anchorsearch {
125 EPSDEBUG { (gs_epsf.ps: found %%BoundingBox\n) print flush } if
126 1 EPSBoundingBoxProcess
128 (%%HiResBoundingBox:) anchorsearch {
130 EPSDEBUG { (gs_epsf.ps: found %%HiResBoundingBox\n) print flush } if
131 3 EPSBoundingBoxProcess
133 pop % Not interested in this DSC comment
140 % Install EPS handler for DSC comments, which we do later
141 /EPSBoundingBoxInit {
142 systemdict /NOEPS known not {
143 % Merge ProcessEPSComment with existing handler
144 /ProcessEPSComment load /exec load
145 currentuserparams /ProcessDSCComment get
146 dup null eq {pop {pop pop}} if /exec load
147 4 array astore cvx readonly
148 << /ProcessDSCComment 3 -1 roll >> setuserparams
152 /.runNoEPS /run load def
154 /.runEPS { % file OR string --
155 /runEPS_save save def
156 /runEPS_dict_count countdictstack def
157 /runEPS_op_count count 2 sub def
158 /runEPS_page_count currentpagedevice /PageCount get def
159 0 EPSBoundingBoxSetState
161 currentpagedevice /PageCount get runEPS_page_count sub 0 eq
162 { /showpage load exec } if
163 count runEPS_op_count sub {pop} repeat
164 countdictstack runEPS_dict_count sub {end} repeat
168 /run { % file OR string --
169 dup type /filetype ne { (r) file } if
170 dup (%!PS-Adobe-) .peekstring {
172 dup (%!PS-Adobe-X.X EPSF-X.X) .peekstring {
175 EPSDEBUG {(runEPS: Found EPS\n) print flush} if
176 systemdict /NOEPS known {
182 EPSDEBUG {(runEPS: Normal DSC\n) print flush} if
188 EPSDEBUG {(runEPS: Short DSC\n) print flush} if
193 EPSDEBUG {(runEPS: Not DSC\n) print flush} if
197 EPSDEBUG {(runEPS: Short non-DSC\n) print flush} if
204 % Handle DOS EPS files.
206 /.runnoepsf /run load def
207 /.epsfheader <C5D0D3C6> def
209 { dup type /filetype ne { (r) file } if
210 % Check for MS-DOS EPSF file (see Red Book p. 729).
212 { .epsfheader eq { dup ( ) readstring exch pop } { false } ifelse }
215 % Stack: file true/false
216 { % This block is executed if the file is MS-DOS EPSF.
217 % Build up the little-endian byte offset and length.
220 { 2 index read not { pop exit } if % if EOF, let error happen
221 2 index mul add exch 256 mul exch
226 % Stack: offset length file
227 % Use flushfile to skip quickly to the start of the
228 % PostScript section.
229 dup 4 -1 roll 12 sub () /SubFileDecode filter flushfile
230 % Now interpret the PostScript.
231 exch () /SubFileDecode filter cvx run
238 % rebind .runstdin to use redefined run
241 { (%stdin) run } execute0