~ubuntu-branches/ubuntu/oneiric/evince/oneiric-updates

« back to all changes in this revision

Viewing changes to dvi/mdvi-lib/sp-epsf.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-01-10 19:35:11 UTC
  • mto: (1.3.1 experimental) (52.1.1 hardy-proposed)
  • mto: This revision was merged to the branch mainline in revision 20.
  • Revision ID: james.westby@ubuntu.com-20070110193511-yjrnndv8e8wv03yy
Tags: upstream-0.7.1
ImportĀ upstreamĀ versionĀ 0.7.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
}