]> git.lizzy.rs Git - plan9front.git/blob - sys/lib/ghostscript/gs_epsf.ps
[12kq]l: remove unix compat code for cputime()
[plan9front.git] / sys / lib / ghostscript / gs_epsf.ps
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   0 EPSBoundingBoxSetState
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