2 |
- |
1 |
% Copyright (C) 1989, 1996, 2002 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 |
|
|
|
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.
|
|
|
19 |
|
|
|
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:
|
|
|
26 |
% gs -dNOEPS file.ps
|
|
|
27 |
|
|
|
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
|
|
|
36 |
|
|
|
37 |
% Parse 4 numbers for a bounding box
|
|
|
38 |
/EPSBoundingBoxParse { % (llx lly urx ury) -- llx lly urx ury true OR false
|
|
|
39 |
mark exch
|
|
|
40 |
token {exch token {exch token {exch token {exch pop} if} if} if} if
|
|
|
41 |
counttomark
|
|
|
42 |
4 eq {
|
|
|
43 |
5 -1 roll pop % remove mark
|
|
|
44 |
true
|
|
|
45 |
} {
|
|
|
46 |
cleartomark false
|
|
|
47 |
} ifelse
|
|
|
48 |
} bind def
|
|
|
49 |
|
|
|
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
|
|
|
60 |
4 2 roll
|
|
|
61 |
exch 4 -1 roll div 3 1 roll exch div
|
|
|
62 |
1 index 1 index lt {pop}{exch pop} ifelse
|
|
|
63 |
dup scale
|
|
|
64 |
% translate to EPS -llx,-lly
|
|
|
65 |
exch neg exch neg translate
|
|
|
66 |
} bind def
|
|
|
67 |
|
|
|
68 |
% Crop the page to the BoundingBox
|
|
|
69 |
/EPSBoundingBoxCrop { % llx lly urx ury --
|
|
|
70 |
EPSDEBUG {
|
|
|
71 |
(gs_epsf.ps: Setting pagesize from EPS bounding box\n) print flush
|
|
|
72 |
} if
|
|
|
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
|
|
|
76 |
} bind def
|
|
|
77 |
|
|
|
78 |
|
|
|
79 |
/EPSBoundingBoxProcess { % (llx lly urx ury) state --
|
|
|
80 |
//systemdict /EPSBoundingBoxState get 1 index lt {
|
|
|
81 |
exch EPSBoundingBoxParse
|
|
|
82 |
{
|
|
|
83 |
//systemdict /EPSCrop known {
|
|
|
84 |
EPSBoundingBoxCrop
|
|
|
85 |
} {
|
|
|
86 |
//systemdict /EPSFitPage known {
|
|
|
87 |
EPSBoundingBoxFitPage
|
|
|
88 |
} {
|
|
|
89 |
% Warn if some of the EPS file will be clipped
|
|
|
90 |
clippath pathbbox newpath
|
|
|
91 |
{ % context for exit
|
|
|
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
|
|
|
96 |
false exit
|
|
|
97 |
} loop
|
|
|
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) =
|
|
|
101 |
flush
|
|
|
102 |
1 add
|
|
|
103 |
} if
|
|
|
104 |
} ifelse
|
|
|
105 |
} ifelse
|
|
|
106 |
EPSBoundingBoxSetState
|
|
|
107 |
} {
|
|
|
108 |
pop % state
|
|
|
109 |
} ifelse
|
|
|
110 |
} {
|
|
|
111 |
pop pop
|
|
|
112 |
} ifelse
|
|
|
113 |
} bind def
|
|
|
114 |
|
|
|
115 |
/ProcessEPSComment { % file comment -- file comment
|
|
|
116 |
//systemdict /EPSBoundingBoxState get 3 lt {
|
|
|
117 |
dup
|
|
|
118 |
(%%EndComments) anchorsearch {
|
|
|
119 |
pop pop
|
|
|
120 |
% ignore any following bounding boxes
|
|
|
121 |
5 EPSBoundingBoxSetState
|
|
|
122 |
} {
|
|
|
123 |
(%%BoundingBox:) anchorsearch {
|
|
|
124 |
pop
|
|
|
125 |
EPSDEBUG { (gs_epsf.ps: found %%BoundingBox\n) print flush } if
|
|
|
126 |
1 EPSBoundingBoxProcess
|
|
|
127 |
} {
|
|
|
128 |
(%%HiResBoundingBox:) anchorsearch {
|
|
|
129 |
pop
|
|
|
130 |
EPSDEBUG { (gs_epsf.ps: found %%HiResBoundingBox\n) print flush } if
|
|
|
131 |
3 EPSBoundingBoxProcess
|
|
|
132 |
} {
|
|
|
133 |
pop % Not interested in this DSC comment
|
|
|
134 |
} ifelse
|
|
|
135 |
} ifelse
|
|
|
136 |
} ifelse
|
|
|
137 |
} if
|
|
|
138 |
} bind def
|
|
|
139 |
|
|
|
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
|
|
|
149 |
} if
|
|
|
150 |
} bind def
|
|
|
151 |
|
|
|
152 |
/.runNoEPS /run load def
|
|
|
153 |
|
|
|
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 |
|
|
|
160 |
.runNoEPS
|
|
|
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
|
|
|
165 |
runEPS_save restore
|
|
|
166 |
} bind def
|
|
|
167 |
|
|
|
168 |
/run { % file OR string --
|
|
|
169 |
dup type /filetype ne { (r) file } if
|
|
|
170 |
dup (%!PS-Adobe-) .peekstring {
|
|
|
171 |
(%!PS-Adobe-) eq {
|
|
|
172 |
dup (%!PS-Adobe-X.X EPSF-X.X) .peekstring {
|
|
|
173 |
(EPSF) search {
|
|
|
174 |
pop pop pop
|
|
|
175 |
EPSDEBUG {(runEPS: Found EPS\n) print flush} if
|
|
|
176 |
systemdict /NOEPS known {
|
|
|
177 |
cvx .runNoEPS
|
|
|
178 |
} {
|
|
|
179 |
cvx .runEPS
|
|
|
180 |
} ifelse
|
|
|
181 |
} {
|
|
|
182 |
EPSDEBUG {(runEPS: Normal DSC\n) print flush} if
|
|
|
183 |
pop
|
|
|
184 |
cvx .runNoEPS
|
|
|
185 |
|
|
|
186 |
} ifelse
|
|
|
187 |
} {
|
|
|
188 |
EPSDEBUG {(runEPS: Short DSC\n) print flush} if
|
|
|
189 |
pop
|
|
|
190 |
cvx .runNoEPS
|
|
|
191 |
} ifelse
|
|
|
192 |
} {
|
|
|
193 |
EPSDEBUG {(runEPS: Not DSC\n) print flush} if
|
|
|
194 |
cvx .runNoEPS
|
|
|
195 |
} ifelse
|
|
|
196 |
} {
|
|
|
197 |
EPSDEBUG {(runEPS: Short non-DSC\n) print flush} if
|
|
|
198 |
pop
|
|
|
199 |
cvx .runNoEPS
|
|
|
200 |
} ifelse
|
|
|
201 |
} bind odef
|
|
|
202 |
|
|
|
203 |
|
|
|
204 |
% Handle DOS EPS files.
|
|
|
205 |
|
|
|
206 |
/.runnoepsf /run load def
|
|
|
207 |
/.epsfheader <C5D0D3C6> def
|
|
|
208 |
/run
|
|
|
209 |
{ dup type /filetype ne { (r) file } if
|
|
|
210 |
% Check for MS-DOS EPSF file (see Red Book p. 729).
|
|
|
211 |
dup ( ) .peekstring
|
|
|
212 |
{ .epsfheader eq { dup ( ) readstring exch pop } { false } ifelse }
|
|
|
213 |
{ pop false }
|
|
|
214 |
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.
|
|
|
218 |
2
|
|
|
219 |
{ 1 0 4
|
|
|
220 |
{ 2 index read not { pop exit } if % if EOF, let error happen
|
|
|
221 |
2 index mul add exch 256 mul exch
|
|
|
222 |
}
|
|
|
223 |
repeat exch pop exch
|
|
|
224 |
}
|
|
|
225 |
repeat
|
|
|
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
|
|
|
232 |
}
|
|
|
233 |
{ .runnoepsf
|
|
|
234 |
}
|
|
|
235 |
ifelse
|
|
|
236 |
} odef
|
|
|
237 |
|
|
|
238 |
% rebind .runstdin to use redefined run
|
|
|
239 |
userdict begin
|
|
|
240 |
/.runstdin {
|
|
|
241 |
{ (%stdin) run } execute0
|
|
|
242 |
} bind def
|
|
|
243 |
end
|