2 * Copyright (C) 2000, Matias Atria
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 /* postscript specials */
53 void epsf_special __PROTO((DviContext *dvi, char *prefix, char *arg));
55 /* Note: the given strings are modified in place */
56 static char *parse_epsf_special(EpsfBox *box, char **ret,
57 char *prefix, char *arg)
79 #define NKEYS (sizeof(keys) / sizeof(keys[0]))
95 /* this special has the form
96 * ["]file.ps["] [key=valye]*
99 /* scan the filename */
100 while(*arg == ' ' || *arg == '\t')
103 /* make a copy of the string */
107 for(name = ++ptr; *ptr && *ptr != '"'; ptr++);
109 for(name = ptr; *ptr && *ptr != ' ' && *ptr != '\t'; ptr++);
115 /* reset values to defaults */
116 for(i = 0; i < NKEYS; i++) {
117 value[i] = atof(keys[i].value);
122 buff_add(&buffer, "@beginspecial ", 0);
130 while(*ptr == ' ' || *ptr == '\t')
134 /* get the whole key=value pair */
135 for(; *ptr && *ptr != ' ' && *ptr != '\t'; ptr++);
138 /* now we shouldn't touch `ptr' anymore */
140 /* now work on this pair */
141 p = strchr(keyname, '=');
148 /* skip until closing quote */
149 while(*p && *p != '"')
153 _("%s: malformed value for key `%s'\n"),
160 for(i = 0; i < NKEYS; i++)
161 if(STRCEQ(keys[i].name, keyname))
164 mdvi_warning(_("%s: unknown key `%s' ignored\n"),
168 if(keys[i].has_arg && val == NULL) {
169 mdvi_warning(_("%s: no argument for key `%s', using defaults\n"),
172 } else if(!keys[i].has_arg && val) {
173 mdvi_warning(_("%s: argument `%s' ignored for key `%s'\n"),
174 filename, val, keyname);
178 value[i] = atof(val);
180 /* put the argument */
181 buff_add(&buffer, val, 0);
182 buff_add(&buffer, " @", 2);
183 buff_add(&buffer, keyname, 0);
184 buff_add(&buffer, " ", 1);
186 /* remember that this option was given */
189 buff_add(&buffer, " @setspecial", 0);
191 /* now compute the bounding box (code comes from dvips) */
200 hsize = value[HSIZE];
202 vsize = value[VSIZE];
204 originx = value[HOFF];
206 originy = value[VOFF];
208 hscale = value[HSCALE] / 100.0;
210 vscale = value[VSCALE] / 100.0;
211 if(present[URX] && present[LLX])
212 hsize = value[URX] - value[LLX];
213 if(present[URY] && present[LLY])
214 vsize = value[URY] - value[LLY];
215 if(present[RWI] || present[RHI]) {
216 if(present[RWI] && !present[RHI])
217 hscale = vscale = value[RWI] / (10.0 * hsize);
218 else if(present[RHI] && !present[RWI])
219 hscale = vscale = value[RHI] / (10.0 * vsize);
221 hscale = value[RWI] / (10.0 * hsize);
222 vscale = value[RHI] / (10.0 * vsize);
228 box->bw = hsize * hscale;
229 box->bh = vsize * vscale;
230 box->angle = value[ANGLE];
237 void epsf_special(DviContext *dvi, char *prefix, char *arg)
243 EpsfBox box = {0, 0, 0, 0};
249 file = parse_epsf_special(&box, &special, prefix, arg);
253 xf = dvi->params.dpi * dvi->params.mag / (72.0 * dvi->params.hshrink);
254 vf = dvi->params.vdpi * dvi->params.mag / (72.0 * dvi->params.vshrink);
255 w = FROUND(box.bw * xf);
256 h = FROUND(box.bh * vf);
257 x = FROUND(box.ox * xf) + dvi->pos.hh;
258 y = FROUND(box.oy * vf) + dvi->pos.vv - h + 1;
260 if (!file || !dvi->device.draw_ps) {
261 dvi->device.draw_rule (dvi, x, y, w, h, 0);
265 if (file[0] == '/') { /* Absolute path */
266 if (stat (file, &buf) == 0)
267 dvi->device.draw_ps (dvi, file, x, y, w, h);
269 dvi->device.draw_rule (dvi, x, y, w, h, 0);
273 tmp = mdvi_strrstr (dvi->filename, "/");
274 if (tmp) { /* Document directory */
275 int path_len = strlen (dvi->filename) - strlen (tmp + 1);
276 int file_len = strlen (file);
278 psfile = mdvi_malloc (path_len + file_len + 1);
280 strncat (psfile, dvi->filename, path_len);
281 strncat (psfile, file, file_len);
283 if (stat (psfile, &buf) == 0) {
284 dvi->device.draw_ps (dvi, psfile, x, y, w, h);
293 psfile = mdvi_build_path_from_cwd (file);
294 if (stat (psfile, &buf) == 0) { /* Current working dir */
295 dvi->device.draw_ps (dvi, psfile, x, y, w, h);
303 psfile = kpse_find_pict (file);
304 if (psfile) { /* kpse */
305 dvi->device.draw_ps (dvi, psfile, x, y, w, h);
307 dvi->device.draw_rule(dvi, x, y, w, h, 0);