Subversion Repositories wimsdev

Rev

Rev 8195 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
10 reyssat 1
/*    Copyright (C) 2002-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
2
 *
3
 *  This program is free software; you can redistribute it and/or modify
4
 *  it under the terms of the GNU General Public License as published by
5
 *  the Free Software Foundation; either version 2 of the License, or
6
 *  (at your option) any later version.
7
 *
8
 *  This program is distributed in the hope that it will be useful,
9
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 *  GNU General Public License for more details.
12
 *
13
 *  You should have received a copy of the GNU General Public License
14
 *  along with this program; if not, write to the Free Software
15
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
 */
8103 bpr 17
#include "texgif.h"
10 reyssat 18
 
19
/* dvi 2 gif driver, dvi interpreter */
8103 bpr 20
#define dvi_set1        128
21
#define dvi_set2        129
22
#define dvi_set3        130
23
#define dvi_set4        131
24
#define dvi_set_rule    132
25
#define dvi_put1        133
26
#define dvi_put2        134
27
#define dvi_put3        135
28
#define dvi_put4        136
29
#define dvi_put_rule    137
30
#define dvi_nop         138
31
#define dvi_bop         139
32
#define dvi_eop         140
33
#define dvi_push        141
34
#define dvi_pop         142
35
#define dvi_right1      143
36
#define dvi_right2      144
37
#define dvi_right3      145
38
#define dvi_right4      146
39
#define dvi_w0          147
40
#define dvi_w1          148
41
#define dvi_w2          149
42
#define dvi_w3          150
43
#define dvi_w4          151
44
#define dvi_x0          152
45
#define dvi_x1          153
46
#define dvi_x2          154
47
#define dvi_x3          155
48
#define dvi_x4          156
49
#define dvi_down1       157
50
#define dvi_down2       158
51
#define dvi_down3       159
52
#define dvi_down4       160
53
#define dvi_y0          161
54
#define dvi_y1          162
55
#define dvi_y2          163
56
#define dvi_y3          164
57
#define dvi_y4          165
58
#define dvi_z0          166
59
#define dvi_z1          167
60
#define dvi_z2          168
61
#define dvi_z3          169
62
#define dvi_z4          170
63
#define dvi_fnt1        235
64
#define dvi_fnt2        236
65
#define dvi_fnt3        237
66
#define dvi_fnt4        238
67
#define dvi_xxx1        239
68
#define dvi_xxx2        240
69
#define dvi_xxx3        241
70
#define dvi_xxx4        242
71
#define dvi_fnt_def1    243
72
#define dvi_fnt_def2    244
73
#define dvi_fnt_def3    245
74
#define dvi_fnt_def4    246
75
#define dvi_pre         247
76
#define dvi_post        248
77
#define dvi_post_post   249
10 reyssat 78
 
79
unsigned char *dvibuf, *dviptr;
80
int dvilen;
81
int pass, passstop;
82
int num, den, mag;
83
int minx, maxx,miny, maxy;
84
double dviratio;
85
int dvix, dviy;
86
int d_h,d_v,d_w,d_x,d_y,d_z;
87
int d_f;
88
int pageptr;
89
struct {
90
    int minx, maxx, miny, maxy;
91
} pagedata[MAX_PAGES];
92
 
93
struct {
94
    int h,v,w,x,y,z;
95
} dvistack[DVI_STACK_LIMIT];
96
int dvistackptr;
97
 
98
#define DVI_post_post   DVI_post
99
void DVI_post(void)
100
{
101
    passstop=-1; dviptr=dvibuf+dvilen;
102
}
103
 
104
void DVI_eop(void)
105
{
106
    if(pass==1) {
107
        pagedata[pageptr].minx=minx;
108
        pagedata[pageptr].maxx=maxx;
109
        pagedata[pageptr].miny=miny;
110
        pagedata[pageptr].maxy=maxy;
111
    }
112
    else saveimage();
113
    pageptr++;
114
    if(*outfile==0 || pageptr>=MAX_PAGES) {
115
        passstop=-1; dviptr=dvibuf+dvilen;
116
    }
117
    else passstop=0;
118
}
119
 
120
void DVI_bop(void)
121
{
122
    passstop=1; dvistackptr=0;
123
    d_h=d_v=d_w=d_x=d_y=d_z=0; d_f=-1;
124
    dviptr+=44;
125
    if(pass==1) {
126
        minx=miny=65536;
127
        maxx=maxy=-1;
128
    }
129
    else {
130
        char *p;
131
        maxx=pagedata[pageptr].maxx;
132
        minx=pagedata[pageptr].minx;
133
        maxy=pagedata[pageptr].maxy;
134
        miny=pagedata[pageptr].miny;
8195 bpr 135
        if(maxx<=minx || maxy<=miny) texgif_error("Empty page.");
10 reyssat 136
        createimage(maxx-minx,maxy-miny);
137
        currentcolor=color_black;
138
        p=getenv("w_instex_color");
139
        if(p!=NULL && *p!=0) makecolor(p);
140
    }
141
}
142
 
143
void DVI_nop(void) {}
144
 
145
int DVI_put(int p)
146
{
147
    int cc, ct, x1, x2, y1, y2;
8195 bpr 148
    if(d_f<0) texgif_error("Bad dvi: trying to put non-existing font.");
10 reyssat 149
    if(p==0) cc=*dviptr; else cc=texint(dviptr+1,p);
150
    dviptr+=p;
151
    if(cc<wfont[d_f].bc || cc>wfont[d_f].ec) return -1;
152
    dvix=rint(dviratio*d_h); dviy=rint(dviratio*d_v);
153
    if(pass==1) {
154
        ct=cc-wfont[d_f].bc;
155
        x1=dvix+wfont[d_f].fh[ct].xstart; y1=dviy+wfont[d_f].fh[ct].ystart;
156
        x2=x1+wfont[d_f].fh[ct].xmax; y2=y1+wfont[d_f].fh[ct].ymax;
11121 georgesk 157
        if(minx>x1) minx=x1;
158
        if(miny>y1) miny=y1;
159
        if(maxx<x2) maxx=x2;
160
        if(maxy<y2) maxy=y2;
10 reyssat 161
    }
162
    else {
163
        paintfont(wfont+d_f,cc,dvix-minx,dviy-miny,currentcolor);
164
    }
165
    return cc;
166
}
167
 
168
void DVI_set(int p)
169
{
170
    int cc;
171
    cc=DVI_put(p);
172
    if(cc<0) return;
173
    d_h+=wfont[d_f].fh[cc-wfont[d_f].bc].w;
174
}
175
 
176
int DVI_put_rule(void)
177
{
178
    int xxx, xx, yy, x1, y1, x2, y2, xx1, xx2, yy1, yy2;
179
    yy=texint(dviptr+1,4); xx=texint(dviptr+5,4); dviptr+=8;
180
    if(xx<=0 || yy<=0) return xx;
181
    xxx=xx;
182
    if(xx>=0) {xx=rint(dviratio*xx+blacker); if(xx>0) xx--;}
183
    else {xx=rint(dviratio*xx-blacker); if(xx<0) xx--;}
184
    if(yy>=0) {yy=rint(dviratio*yy+blacker); if(yy>0) yy--;}
185
    else {yy=rint(dviratio*yy-blacker); if(yy<0) yy--;}
186
    if(pass==1) {
187
        x1=rint(dviratio*d_h); y2=rint(dviratio*d_v);
188
        x2=x1+xx; y1=y2-yy;
189
        if(x1<x2) {xx1=x1; xx2=x2;} else {xx1=x2; xx2=x1;}
190
        if(y1<y2) {yy1=y1; yy2=y2;} else {yy1=y2; yy2=y1;}
11121 georgesk 191
        if(minx>x1) minx=x1;
192
        if(miny>y1) miny=y1;
193
        if(maxx<x2) maxx=x2;
194
        if(maxy<y2) maxy=y2;
10 reyssat 195
    }
196
    else {
197
        x1=rint(dviratio*d_h)-minx; y1=rint(dviratio*d_v)-miny;
198
        x2=x1+xx; y2=y1-yy;
199
        if(x1<x2) {xx1=x1; xx2=x2;} else {xx1=x2; xx2=x1;}
200
        if(y1<y2) {yy1=y1; yy2=y2;} else {yy1=y2; yy2=y1;}
201
        gdImageFilledRectangle(image,xx1,yy1,xx2,yy2,currentcolor);
202
    }
203
    return xxx;
204
}
205
 
206
void DVI_set_rule(void)
207
{
208
    d_h+=DVI_put_rule();
209
}
210
 
211
void DVI_fnt_num(int p)
212
{
213
    int fnum;
214
    if(p==0) fnum=*dviptr-171; else fnum=texint(dviptr+1,p);
215
    dviptr+=p;
216
    for(d_f=0; d_f<fontcnt && wfont[d_f].num!=fnum; d_f++);
8195 bpr 217
    if(d_f>=fontcnt) texgif_error("Bad dvi: using font before defining it.");
10 reyssat 218
}
219
 
220
void DVI_fnt_def(int p)
221
{
222
    int i, fnum, fdensity;
223
    char fname[1024];
224
    unsigned long int c,s,d,a,l;
225
    double fratio;
226
    union { unsigned long c; char C[4]; } U;
227
 
8195 bpr 228
    if(fontcnt>=FONT_NUMBER_LIMIT) texgif_error("Font number exceeded design capacity.");
10 reyssat 229
    fnum=texint(++dviptr,p); dviptr+=p;
230
    for (i = 0; i <= 3; i++) U.C[i] = dviptr[i];
231
    c=U.c; dviptr+=4;
232
    s=texint(dviptr,4); dviptr+=4;
233
    d=texint(dviptr,4); dviptr+=4;
234
    a=*dviptr++; l=*dviptr++;
8195 bpr 235
    if(a+l>1000 || a+l<1) texgif_error("Bad dvi: bad font name.");
10 reyssat 236
    memmove(fname,dviptr,a+l); fname[a+l]=0; dviptr+=a+l-1;
237
    if(pass==1) {
238
        fdensity=(double) density*((double) s/d);
239
        if(loadfont(fname, c, fdensity, wfont+fontcnt)==NULL) {
8100 bpr 240
            if(loadfont("cmr10",0,fdensity,wfont+fontcnt)==NULL)
8195 bpr 241
              texgif_error("Font panick: even cmr10 cannot be found.");
10 reyssat 242
            else fprintf(stderr,"Font %s not found; replace by cmr10.\n",fname);
243
        }
244
        wfont[fontcnt].num=fnum;
245
        fratio=(double) s/wfont[fontcnt].designsize*d/65536;
246
        for(i=0;i<wfont[fontcnt].cnt; i++)
247
          wfont[fontcnt].fh[i].w=fratio*wfont[fontcnt].fh[i].w;
248
        fontcnt++;
249
    }
250
}
251
 
252
void DVI_push(void)
253
{
8195 bpr 254
    if(dvistackptr>=DVI_STACK_LIMIT) texgif_error("dvi stack overflow.");
10 reyssat 255
    dvistack[dvistackptr].h=d_h;
256
    dvistack[dvistackptr].v=d_v;
257
    dvistack[dvistackptr].w=d_w;
258
    dvistack[dvistackptr].x=d_x;
259
    dvistack[dvistackptr].y=d_y;
260
    dvistack[dvistackptr].z=d_z;
261
    dvistackptr++;
262
}
263
 
264
void DVI_pop(void)
265
{
8195 bpr 266
    if(dvistackptr<=0) texgif_error("Bad dvi file: dvi stack underflow.");
10 reyssat 267
    dvistackptr--;
268
    d_h=dvistack[dvistackptr].h;
269
    d_v=dvistack[dvistackptr].v;
270
    d_w=dvistack[dvistackptr].w;
271
    d_x=dvistack[dvistackptr].x;
272
    d_y=dvistack[dvistackptr].y;
273
    d_z=dvistack[dvistackptr].z;
274
}
275
 
276
void DVI_move(int *hv, int p)
277
{
278
    int t;
279
    t=texintsigned(dviptr+1,p); dviptr+=p;
280
    *hv+=t;
281
}
282
 
283
void DVI_move2(int *hv, int *xyz, int p)
284
{
285
    if(p>0) *xyz=texintsigned(dviptr+1,p);
286
    *hv+=*xyz;
287
    dviptr+=p;
288
}
289
 
290
void DVI_xxx(int p)
291
{
292
    int i, t;
293
    char *pp, buf[1024];
8100 bpr 294
 
10 reyssat 295
    t=texint(dviptr+1,p);
296
    if(pass<2 || t>1000) {dviptr+=t+p; return;}
297
    memmove(buf,dviptr+1+1,t); buf[t]=0;
298
    dviptr+=t+p;
299
    for(i=0;i<t;i++) buf[i]=tolower(buf[i]);
300
    if(strncmp(buf,"color",5)!=0) return;
301
    pp=find_word_start(buf+5); if(*pp!='=') return;
302
    makecolor(pp+1);
303
}
304
 
305
        /* load and interprete dvi file */
306
void dvi(void)
307
{
308
    unsigned char cc, *startpoint;
309
    char namebuf[1024];
8100 bpr 310
 
10 reyssat 311
    snprintf(namebuf,sizeof(namebuf),"%s/texgif.dvi",tmpdir);
312
    dvilen=getfile(namebuf,&dvibuf);
8195 bpr 313
    if(dvilen<=0) texgif_error("dvi file not found.");
10 reyssat 314
    dviptr=dvibuf; fontcnt=0;
315
    if(*dviptr++!=dvi_pre || *dviptr++!=2) {
8195 bpr 316
        /* baddvi: */ texgif_error("Bad dvi file header.");
10 reyssat 317
    }
318
    num=texint(dviptr,4); dviptr+=4;
319
    den=texint(dviptr,4); dviptr+=4;
320
    mag=texint(dviptr,4); dviptr+=4;
321
    cc=*dviptr++; dviptr+=cc; startpoint=dviptr;
322
    density=rint((double) compressratio*mag*basedensity/1000);
323
    dviratio=(double) num/den*density/254000;
324
printf("dvi file: num=%d, den=%d, ratio=%f, mag=%d, density=%d\n",
325
       num,den,dviratio, mag, density);
326
    for(pass=1; pass<=2; pass++) {
327
        passstop=0; d_f=-1; pageptr=0;
328
        for(dviptr=startpoint; dviptr<dvibuf+dvilen && passstop>=0; dviptr++) {
329
            if(*dviptr<128) {
330
                DVI_set(0); continue;
331
            }
332
            if(*dviptr>=171 && *dviptr<=234) {
333
                DVI_fnt_num(0); continue;
334
            }
335
            switch(*dviptr) {
336
                case dvi_set1: case dvi_set2: case dvi_set3:
337
                case dvi_set4: DVI_set(*dviptr-dvi_set1+1); break;
338
                case dvi_set_rule: DVI_set_rule(); break;
8100 bpr 339
 
10 reyssat 340
                case dvi_put1: case dvi_put2: case dvi_put3:
341
                case dvi_put4: DVI_put(*dviptr-dvi_put1+1); break;
342
                case dvi_put_rule: DVI_put_rule(); break;
8100 bpr 343
 
10 reyssat 344
                case dvi_nop: DVI_nop(); break;
345
                case dvi_bop: DVI_bop(); break;
346
                case dvi_eop: DVI_eop(); break;
347
                case dvi_push: DVI_push(); break;
348
                case dvi_pop: DVI_pop(); break;
8100 bpr 349
 
10 reyssat 350
                case dvi_right1: case dvi_right2: case dvi_right3:
351
                case dvi_right4: DVI_move(&d_h, *dviptr-dvi_right1+1); break;
8100 bpr 352
 
10 reyssat 353
                case dvi_w0: case dvi_w1: case dvi_w2: case dvi_w3:
354
                case dvi_w4: DVI_move2(&d_h, &d_w, *dviptr-dvi_w0); break;
355
                case dvi_x0: case dvi_x1: case dvi_x2: case dvi_x3:
356
                case dvi_x4: DVI_move2(&d_h, &d_x, *dviptr-dvi_x0); break;
8100 bpr 357
 
10 reyssat 358
                case dvi_down1: case dvi_down2: case dvi_down3:
359
                case dvi_down4: DVI_move(&d_v, *dviptr-dvi_down1+1); break;
8100 bpr 360
 
10 reyssat 361
                case dvi_y0: case dvi_y1: case dvi_y2: case dvi_y3:
362
                case dvi_y4: DVI_move2(&d_v, &d_y, *dviptr-dvi_y0); break;
363
                case dvi_z0: case dvi_z1: case dvi_z2: case dvi_z3:
364
                case dvi_z4: DVI_move2(&d_v, &d_z, *dviptr-dvi_z0); break;
8100 bpr 365
 
10 reyssat 366
                case dvi_fnt1: case dvi_fnt2: case dvi_fnt3:
367
                case dvi_fnt4: DVI_fnt_num(*dviptr-dvi_fnt1+1); break;
8100 bpr 368
 
10 reyssat 369
                case dvi_xxx1: case dvi_xxx2: case dvi_xxx3:
370
                case dvi_xxx4: DVI_xxx(*dviptr-dvi_xxx1+1); break;
8100 bpr 371
 
10 reyssat 372
                case dvi_fnt_def1: case dvi_fnt_def2: case dvi_fnt_def3:
373
                case dvi_fnt_def4: DVI_fnt_def(*dviptr-dvi_fnt_def1+1); break;
8100 bpr 374
 
8195 bpr 375
                case dvi_pre: texgif_error("Bad dvi file: pre within file.");
10 reyssat 376
                case dvi_post: DVI_post(); break;
377
                case dvi_post_post: DVI_post_post(); break;
8100 bpr 378
 
8195 bpr 379
                default: texgif_error("Bad dvi file: unknown command.");
10 reyssat 380
            }
381
        }
382
    }
383
    free(dvibuf);
384
}
385