]> www.fi.muni.cz Git - evince.git/blob - backend/dvi/mdvi-lib/sp-epsf.c
Reorganize source tree.
[evince.git] / backend / dvi / mdvi-lib / sp-epsf.c
1 /*
2  * Copyright (C) 2000, Matias Atria
3  *
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.
8  *
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.
13  *
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
17  */
18
19 /* postscript specials */
20
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "mdvi.h"
25 #include "private.h"
26
27 typedef struct {
28         double  ox;
29         double  oy;
30         double  bw;
31         double  bh;
32         double  angle;
33 } EpsfBox;
34
35 #define LLX     0
36 #define LLY     1
37 #define URX     2
38 #define URY     3
39 #define RWI     4
40 #define RHI     5
41 #define HOFF    6
42 #define VOFF    7
43 #define HSIZE   8
44 #define VSIZE   9
45 #define HSCALE  10
46 #define VSCALE  11
47 #define ANGLE   12
48 #define CLIP    13
49
50 void    epsf_special __PROTO((DviContext *dvi, char *prefix, char *arg));
51
52 /* Note: the given strings are modified in place */
53 static char *parse_epsf_special(EpsfBox *box, char **ret, 
54         char *prefix, char *arg)
55 {
56         static struct {
57                 char *name;
58                 int  has_arg;
59                 char *value;
60         } keys[] = {
61                 {"llx", 1, "0"},
62                 {"lly", 1, "0"},
63                 {"urx", 1, "0"},
64                 {"ury", 1, "0"},
65                 {"rwi", 1, "0"},
66                 {"rhi", 1, "0"},
67                 {"hoffset", 1, "0"},
68                 {"voffset", 1, "0"},
69                 {"hsize", 1, "612"},
70                 {"vsize", 1, "792"},
71                 {"hscale", 1, "100"},
72                 {"vscale", 1, "100"},
73                 {"angle", 1, "0"},
74                 {"clip", 0, "0"}
75         };
76 #define NKEYS   (sizeof(keys) / sizeof(keys[0]))
77         char    *ptr;
78         char    *filename;
79         int     quoted;
80         double  value[NKEYS];
81         Uchar   present[NKEYS];
82         Buffer  buffer;
83         char    *name;
84         int     i;
85         double  originx;
86         double  originy;
87         double  hsize;
88         double  vsize;
89         double  hscale;
90         double  vscale;
91                 
92         /* this special has the form
93          *   ["]file.ps["] [key=valye]*
94          */
95         
96         /* scan the filename */
97         while(*arg == ' ' || *arg == '\t')
98                 arg++;
99
100         /* make a copy of the string */
101         ptr = arg;
102
103         if(*ptr == '"')
104                 for(name = ++ptr; *ptr && *ptr != '"'; ptr++);
105         else
106                 for(name = ptr; *ptr && *ptr != ' ' && *ptr != '\t'; ptr++);
107         if(ptr == name)
108                 return NULL;
109         *ptr++ = 0;
110         filename = name;
111
112         /* reset values to defaults */
113         for(i = 0; i < NKEYS; i++) {
114                 value[i] = atof(keys[i].value);
115                 present[i] = 0;
116         }
117         
118         buff_init(&buffer);
119         buff_add(&buffer, "@beginspecial ", 0);
120
121         quoted = 0;
122         while(*ptr) {
123                 const char *keyname;
124                 char    *val;
125                 char    *p;
126
127                 while(*ptr == ' ' || *ptr == '\t')
128                         ptr++;
129                 keyname = ptr;
130                 
131                 /* get the whole key=value pair */
132                 for(; *ptr && *ptr != ' ' && *ptr != '\t'; ptr++);
133                 
134                 if(*ptr) *ptr++ = 0;
135                 /* now we shouldn't touch `ptr' anymore */
136                 
137                 /* now work on this pair */
138                 p = strchr(keyname, '=');
139                 if(p == NULL)
140                         val = NULL;
141                 else {
142                         *p++ = 0;
143                         if(*p == '"') {
144                                 val = ++p;
145                                 /* skip until closing quote */
146                                 while(*p && *p != '"')
147                                         p++;
148                                 if(*p != '"')
149                                         warning(
150                                         _("%s: malformed value for key `%s'\n"),
151                                                 filename, keyname);
152                         } else
153                                 val = p;
154                 }
155
156                 /* lookup the key */
157                 for(i = 0; i < NKEYS; i++)
158                         if(STRCEQ(keys[i].name, keyname))
159                                 break;
160                 if(i == NKEYS) {
161                         warning(_("%s: unknown key `%s' ignored\n"),
162                                 filename, keyname);
163                         continue;
164                 }
165                 if(keys[i].has_arg && val == NULL) {
166                         warning(_("%s: no argument for key `%s', using defaults\n"),
167                                 filename, keyname);
168                         val = keys[i].value;
169                 } else if(!keys[i].has_arg && val) {
170                         warning(_("%s: argument `%s' ignored for key `%s'\n"),
171                                 filename, val, keyname);
172                         val = NULL;
173                 }
174                 if(val)
175                         value[i] = atof(val);
176                 
177                 /* put the argument */
178                 buff_add(&buffer, val, 0);
179                 buff_add(&buffer, " @", 2);
180                 buff_add(&buffer, keyname, 0);
181                 buff_add(&buffer, " ", 1);
182                 
183                 /* remember that this option was given */
184                 present[i] = 0xff;
185         }
186         buff_add(&buffer, " @setspecial", 0);
187         
188         /* now compute the bounding box (code comes from dvips) */
189         originx = 0;
190         originy = 0;
191         hscale = 1;
192         vscale = 1;
193         hsize = 0;
194         vsize = 0;
195         
196         if(present[HSIZE])
197                 hsize = value[HSIZE];
198         if(present[VSIZE])
199                 vsize = value[VSIZE];
200         if(present[HOFF])
201                 originx = value[HOFF];
202         if(present[VOFF])
203                 originy = value[VOFF];
204         if(present[HSCALE])
205                 hscale = value[HSCALE] / 100.0;
206         if(present[VSCALE])
207                 vscale = value[VSCALE] / 100.0;
208         if(present[URX] && present[LLX])
209                 hsize = value[URX] - value[LLX];
210         if(present[URY] && present[LLY])
211                 vsize = value[URY] - value[LLY];
212         if(present[RWI] || present[RHI]) {
213                 if(present[RWI] && !present[RHI])
214                         hscale = vscale = value[RWI] / (10.0 * hsize);
215                 else if(present[RHI] && !present[RWI])
216                         hscale = vscale = value[RHI] / (10.0 * vsize);
217                 else {
218                         hscale = value[RWI] / (10.0 * hsize);
219                         vscale = value[RHI] / (10.0 * vsize);
220                 }
221         }
222         
223         box->ox = originx;
224         box->oy = originy;
225         box->bw = hsize * hscale;
226         box->bh = vsize * vscale;
227         box->angle = value[ANGLE];
228
229         *ret = buffer.data;
230         
231         return filename;
232 }
233
234 void    epsf_special(DviContext *dvi, char *prefix, char *arg)
235 {
236         char    *file;
237         char    *special;
238         EpsfBox box = {0, 0, 0, 0};
239         int     x, y;
240         int     w, h;
241         double  xf, vf;
242         
243         file = parse_epsf_special(&box, &special, prefix, arg);
244         if(file != NULL)
245                 mdvi_free(special);
246         /* 
247          * draw the bounding box. Notice that it is in PostScript units,
248          * so we have to convert it into pixels
249          */
250         xf = dvi->params.dpi * dvi->params.mag / (72.0 * dvi->params.hshrink);
251         vf = dvi->params.vdpi * dvi->params.mag / (72.0 * dvi->params.vshrink);
252         x = FROUND(box.ox * xf);
253         y = FROUND(box.oy * vf);
254         w = FROUND(box.bw * xf);
255         h = FROUND(box.bh * vf);
256         dvi->device.draw_rule(dvi, dvi->pos.hh + x, dvi->pos.vv + y - h + 1, w, h, 0);
257 }