1 |
% EPSF.TEX macro file: |
2 |
% Written by Tomas Rokicki of Radical Eye Software, 29 Mar 1989. |
3 |
% Revised by Don Knuth, 3 Jan 1990. |
4 |
% Revised by Tomas Rokicki to accept bounding boxes with no |
5 |
% space after the colon, 18 Jul 1990. |
6 |
% |
7 |
% TeX macros to include an Encapsulated PostScript graphic. |
8 |
% Works by finding the bounding box comment, |
9 |
% calculating the correct scale values, and inserting a vbox |
10 |
% of the appropriate size at the current position in the TeX document. |
11 |
% |
12 |
% To use with the center environment of LaTeX, preface the \epsffile |
13 |
% call with a \leavevmode. (LaTeX should probably supply this itself |
14 |
% for the center environment.) |
15 |
% |
16 |
% To use, simply say |
17 |
% \input epsf % somewhere early on in your TeX file |
18 |
% \epsfbox{filename.ps} % where you want to insert a vbox for a figure |
19 |
% |
20 |
% Alternatively, you can type |
21 |
% |
22 |
% \epsfbox[0 0 30 50]{filename.ps} % to supply your own BB |
23 |
% |
24 |
% which will not read in the file, and will instead use the bounding |
25 |
% box you specify. |
26 |
% |
27 |
% The effect will be to typeset the figure as a TeX box, at the |
28 |
% point of your \epsfbox command. By default, the graphic will have its |
29 |
% `natural' width (namely the width of its bounding box, as described |
30 |
% in filename.ps). The TeX box will have depth zero. |
31 |
% |
32 |
% You can enlarge or reduce the figure by saying |
33 |
% \epsfxsize=<dimen> \epsfbox{filename.ps} |
34 |
% (or |
35 |
% \epsfysize=<dimen> \epsfbox{filename.ps}) |
36 |
% instead. Then the width of the TeX box will be \epsfxsize and its |
37 |
% height will be scaled proportionately (or the height will be |
38 |
% \epsfysize and its width will be scaled proportiontally). The |
39 |
% width (and height) is restored to zero after each use. |
40 |
% |
41 |
% A more general facility for sizing is available by defining the |
42 |
% \epsfsize macro. Normally you can redefine this macro |
43 |
% to do almost anything. The first parameter is the natural x size of |
44 |
% the PostScript graphic, the second parameter is the natural y size |
45 |
% of the PostScript graphic. It must return the xsize to use, or 0 if |
46 |
% natural scaling is to be used. Common uses include: |
47 |
% |
48 |
% \epsfxsize % just leave the old value alone |
49 |
% 0pt % use the natural sizes |
50 |
% #1 % use the natural sizes |
51 |
% \hsize % scale to full width |
52 |
% 0.5#1 % scale to 50% of natural size |
53 |
% \ifnum#1>\hsize\hsize\else#1\fi % smaller of natural, hsize |
54 |
% |
55 |
% If you want TeX to report the size of the figure (as a message |
56 |
% on your terminal when it processes each figure), say `\epsfverbosetrue'. |
57 |
% |
58 |
\newread\epsffilein % file to \read |
59 |
\newif\ifepsffileok % continue looking for the bounding box? |
60 |
\newif\ifepsfbbfound % success? |
61 |
\newif\ifepsfverbose % report what you're making? |
62 |
\newdimen\epsfxsize % horizontal size after scaling |
63 |
\newdimen\epsfysize % vertical size after scaling |
64 |
\newdimen\epsftsize % horizontal size before scaling |
65 |
\newdimen\epsfrsize % vertical size before scaling |
66 |
\newdimen\epsftmp % register for arithmetic manipulation |
67 |
\newdimen\pspoints % conversion factor |
68 |
% |
69 |
\pspoints=1bp % Adobe points are `big' |
70 |
\epsfxsize=0pt % Default value, means `use natural size' |
71 |
\epsfysize=0pt % ditto |
72 |
% |
73 |
\def\epsfbox#1{\global\def\epsfllx{72}\global\def\epsflly{72}% |
74 |
\global\def\epsfurx{540}\global\def\epsfury{720}% |
75 |
\def\lbracket{[}\def\testit{#1}\ifx\testit\lbracket |
76 |
\let\next=\epsfgetlitbb\else\let\next=\epsfnormal\fi\next{#1}}% |
77 |
% |
78 |
\def\epsfgetlitbb#1#2 #3 #4 #5]#6{\epsfgrab #2 #3 #4 #5 .\\% |
79 |
\epsfsetgraph{#6}}% |
80 |
% |
81 |
\def\epsfnormal#1{\epsfgetbb{#1}\epsfsetgraph{#1}}% |
82 |
% |
83 |
\def\epsfgetbb#1{% |
84 |
% |
85 |
% The first thing we need to do is to open the |
86 |
% PostScript file, if possible. |
87 |
% |
88 |
\openin\epsffilein=#1 |
89 |
\ifeof\epsffilein\errmessage{I couldn't open #1, will ignore it}\else |
90 |
% |
91 |
% Okay, we got it. Now we'll scan lines until we find one that doesn't |
92 |
% start with %. We're looking for the bounding box comment. |
93 |
% |
94 |
{\epsffileoktrue \chardef\other=12 |
95 |
\def\do##1{\catcode`##1=\other}\dospecials \catcode`\ =10 |
96 |
\loop |
97 |
\read\epsffilein to \epsffileline |
98 |
\ifeof\epsffilein\epsffileokfalse\else |
99 |
% |
100 |
% We check to see if the first character is a % sign; |
101 |
% if not, we stop reading (unless the line was entirely blank); |
102 |
% if so, we look further and stop only if the line begins with |
103 |
% `%%BoundingBox:'. |
104 |
% |
105 |
\expandafter\epsfaux\epsffileline:. \\% |
106 |
\fi |
107 |
\ifepsffileok\repeat |
108 |
\ifepsfbbfound\else |
109 |
\ifepsfverbose\message{No bounding box comment in #1; using defaults}\fi\fi |
110 |
}\closein\epsffilein\fi}% |
111 |
% |
112 |
% Now we have to calculate the scale and offset values to use. |
113 |
% First we compute the natural sizes. |
114 |
% |
115 |
\def\epsfclipstring{}% do we clip or not? If so, |
116 |
\def\epsfclipon{\def\epsfclipstring{ clip}}% |
117 |
\def\epsfclipoff{\def\epsfclipstring{}}% |
118 |
% |
119 |
\def\epsfsetgraph#1{% |
120 |
\epsfrsize=\epsfury\pspoints |
121 |
\advance\epsfrsize by-\epsflly\pspoints |
122 |
\epsftsize=\epsfurx\pspoints |
123 |
\advance\epsftsize by-\epsfllx\pspoints |
124 |
% |
125 |
% If `epsfxsize' is 0, we default to the natural size of the picture. |
126 |
% Otherwise we scale the graph to be \epsfxsize wide. |
127 |
% |
128 |
\epsfxsize\epsfsize\epsftsize\epsfrsize |
129 |
\ifnum\epsfxsize=0 \ifnum\epsfysize=0 |
130 |
\epsfxsize=\epsftsize \epsfysize=\epsfrsize |
131 |
\epsfrsize=0pt |
132 |
% |
133 |
% We have a sticky problem here: TeX doesn't do floating point arithmetic! |
134 |
% Our goal is to compute y = rx/t. The following loop does this reasonably |
135 |
% fast, with an error of at most about 16 sp (about 1/4000 pt). |
136 |
% |
137 |
\else\epsftmp=\epsftsize \divide\epsftmp\epsfrsize |
138 |
\epsfxsize=\epsfysize \multiply\epsfxsize\epsftmp |
139 |
\multiply\epsftmp\epsfrsize \advance\epsftsize-\epsftmp |
140 |
\epsftmp=\epsfysize |
141 |
\loop \advance\epsftsize\epsftsize \divide\epsftmp 2 |
142 |
\ifnum\epsftmp>0 |
143 |
\ifnum\epsftsize<\epsfrsize\else |
144 |
\advance\epsftsize-\epsfrsize \advance\epsfxsize\epsftmp \fi |
145 |
\repeat |
146 |
\epsfrsize=0pt |
147 |
\fi |
148 |
\else \ifnum\epsfysize=0 |
149 |
\epsftmp=\epsfrsize \divide\epsftmp\epsftsize |
150 |
\epsfysize=\epsfxsize \multiply\epsfysize\epsftmp |
151 |
\multiply\epsftmp\epsftsize \advance\epsfrsize-\epsftmp |
152 |
\epsftmp=\epsfxsize |
153 |
\loop \advance\epsfrsize\epsfrsize \divide\epsftmp 2 |
154 |
\ifnum\epsftmp>0 |
155 |
\ifnum\epsfrsize<\epsftsize\else |
156 |
\advance\epsfrsize-\epsftsize \advance\epsfysize\epsftmp \fi |
157 |
\repeat |
158 |
\epsfrsize=0pt |
159 |
\else |
160 |
\epsfrsize=\epsfysize |
161 |
\fi |
162 |
\fi |
163 |
% |
164 |
% Finally, we make the vbox and stick in a \special that dvips can parse. |
165 |
% |
166 |
\ifepsfverbose\message{#1: width=\the\epsfxsize, height=\the\epsfysize}\fi |
167 |
\epsftmp=10\epsfxsize \divide\epsftmp\pspoints |
168 |
\vbox to\epsfysize{\vfil\hbox to\epsfxsize{% |
169 |
\ifnum\epsfrsize=0\relax |
170 |
\special{PSfile=#1 llx=\epsfllx\space lly=\epsflly\space |
171 |
urx=\epsfurx\space ury=\epsfury\space rwi=\number\epsftmp |
172 |
\epsfclipstring}% |
173 |
\else |
174 |
\epsfrsize=10\epsfysize \divide\epsfrsize\pspoints |
175 |
\special{PSfile=#1 llx=\epsfllx\space lly=\epsflly\space |
176 |
urx=\epsfurx\space ury=\epsfury\space rwi=\number\epsftmp\space |
177 |
rhi=\number\epsfrsize \epsfclipstring}% |
178 |
\fi |
179 |
\hfil}}% |
180 |
\global\epsfxsize=0pt\global\epsfysize=0pt}% |
181 |
% |
182 |
% We still need to define the tricky \epsfaux macro. This requires |
183 |
% a couple of magic constants for comparison purposes. |
184 |
% |
185 |
{\catcode`\%=12 \global\let\epsfpercent=%\global\def\epsfbblit{%BoundingBox}}% |
186 |
% |
187 |
% So we're ready to check for `%BoundingBox:' and to grab the |
188 |
% values if they are found. |
189 |
% |
190 |
\long\def\epsfaux#1#2:#3\\{\ifx#1\epsfpercent |
191 |
\def\testit{#2}\ifx\testit\epsfbblit |
192 |
\epsfgrab #3 . . . \\% |
193 |
\epsffileokfalse |
194 |
\global\epsfbbfoundtrue |
195 |
\fi\else\ifx#1\par\else\epsffileokfalse\fi\fi}% |
196 |
% |
197 |
% Here we grab the values and stuff them in the appropriate definitions. |
198 |
% |
199 |
\def\epsfempty{}% |
200 |
\def\epsfgrab #1 #2 #3 #4 #5\\{% |
201 |
\global\def\epsfllx{#1}\ifx\epsfllx\epsfempty |
202 |
\epsfgrab #2 #3 #4 #5 .\\\else |
203 |
\global\def\epsflly{#2}% |
204 |
\global\def\epsfurx{#3}\global\def\epsfury{#4}\fi}% |
205 |
% |
206 |
% We default the epsfsize macro. |
207 |
% |
208 |
\def\epsfsize#1#2{\epsfxsize} |
209 |
% |
210 |
% Finally, another definition for compatibility with older macros. |
211 |
% |
212 |
\let\epsffile=\epsfbox |
213 |
|