- /*    Copyright (C) 2002-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis 
-  * 
-  *  This program is free software; you can redistribute it and/or modify 
-  *  it under the terms of the GNU General Public License as published by 
-  *  the Free Software Foundation; either version 2 of the License, or 
-  *  (at your option) any later version. 
-  * 
-  *  This program is distributed in the hope that it will be useful, 
-  *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
-  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
-  *  GNU General Public License for more details. 
-  * 
-  *  You should have received a copy of the GNU General Public License 
-  *  along with this program; if not, write to the Free Software 
-  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
-  */ 
- #include "texgif.h" 
-   
- /* dvi 2 gif driver, dvi interpreter */ 
- #define dvi_set1        128 
- #define dvi_set2        129 
- #define dvi_set3        130 
- #define dvi_set4        131 
- #define dvi_set_rule    132 
- #define dvi_put1        133 
- #define dvi_put2        134 
- #define dvi_put3        135 
- #define dvi_put4        136 
- #define dvi_put_rule    137 
- #define dvi_nop         138 
- #define dvi_bop         139 
- #define dvi_eop         140 
- #define dvi_push        141 
- #define dvi_pop         142 
- #define dvi_right1      143 
- #define dvi_right2      144 
- #define dvi_right3      145 
- #define dvi_right4      146 
- #define dvi_w0          147 
- #define dvi_w1          148 
- #define dvi_w2          149 
- #define dvi_w3          150 
- #define dvi_w4          151 
- #define dvi_x0          152 
- #define dvi_x1          153 
- #define dvi_x2          154 
- #define dvi_x3          155 
- #define dvi_x4          156 
- #define dvi_down1       157 
- #define dvi_down2       158 
- #define dvi_down3       159 
- #define dvi_down4       160 
- #define dvi_y0          161 
- #define dvi_y1          162 
- #define dvi_y2          163 
- #define dvi_y3          164 
- #define dvi_y4          165 
- #define dvi_z0          166 
- #define dvi_z1          167 
- #define dvi_z2          168 
- #define dvi_z3          169 
- #define dvi_z4          170 
- #define dvi_fnt1        235 
- #define dvi_fnt2        236 
- #define dvi_fnt3        237 
- #define dvi_fnt4        238 
- #define dvi_xxx1        239 
- #define dvi_xxx2        240 
- #define dvi_xxx3        241 
- #define dvi_xxx4        242 
- #define dvi_fnt_def1    243 
- #define dvi_fnt_def2    244 
- #define dvi_fnt_def3    245 
- #define dvi_fnt_def4    246 
- #define dvi_pre         247 
- #define dvi_post        248 
- #define dvi_post_post   249 
-   
- unsigned char *dvibuf, *dviptr; 
- int dvilen; 
- int pass, passstop; 
- int num, den, mag; 
- int minx, maxx,miny, maxy; 
- double dviratio; 
- int dvix, dviy; 
- int d_h,d_v,d_w,d_x,d_y,d_z; 
- int d_f; 
- int pageptr; 
- struct { 
-     int minx, maxx, miny, maxy; 
- } pagedata[MAX_PAGES]; 
-   
- struct { 
-     int h,v,w,x,y,z; 
- } dvistack[DVI_STACK_LIMIT]; 
- int dvistackptr; 
-   
- #define DVI_post_post   DVI_post 
- void DVI_post(void) 
- { 
-     passstop=-1; dviptr=dvibuf+dvilen; 
- } 
-   
- void DVI_eop(void) 
- { 
-     if(pass==1) { 
-         pagedata[pageptr].minx=minx; 
-         pagedata[pageptr].maxx=maxx; 
-         pagedata[pageptr].miny=miny; 
-         pagedata[pageptr].maxy=maxy; 
-     } 
-     else saveimage(); 
-     pageptr++; 
-     if(*outfile==0 || pageptr>=MAX_PAGES) { 
-         passstop=-1; dviptr=dvibuf+dvilen; 
-     } 
-     else passstop=0; 
- } 
-   
- void DVI_bop(void) 
- { 
-     passstop=1; dvistackptr=0; 
-     d_h=d_v=d_w=d_x=d_y=d_z=0; d_f=-1; 
-     dviptr+=44; 
-     if(pass==1) { 
-         minx=miny=65536; 
-         maxx=maxy=-1; 
-     } 
-     else { 
-         char *p; 
-         maxx=pagedata[pageptr].maxx; 
-         minx=pagedata[pageptr].minx; 
-         maxy=pagedata[pageptr].maxy; 
-         miny=pagedata[pageptr].miny; 
-         if(maxx<=minx || maxy<=miny) error("Empty page."); 
-         createimage(maxx-minx,maxy-miny); 
-         currentcolor=color_black; 
-         if(p!=NULL && *p!=0) makecolor(p); 
-     } 
- } 
-   
- void DVI_nop(void) {} 
-   
- int DVI_put(int p) 
- { 
-     int cc, ct, x1, x2, y1, y2; 
-     if(d_f<0) error("Bad dvi: trying to put non-existing font."); 
-     if(p==0) cc=*dviptr; else cc=texint(dviptr+1,p); 
-     dviptr+=p; 
-     if(cc<wfont[d_f].bc || cc>wfont[d_f].ec) return -1; 
-     dvix=rint(dviratio*d_h); dviy=rint(dviratio*d_v); 
-     if(pass==1) { 
-         ct=cc-wfont[d_f].bc; 
-         x1=dvix+wfont[d_f].fh[ct].xstart; y1=dviy+wfont[d_f].fh[ct].ystart; 
-         x2=x1+wfont[d_f].fh[ct].xmax; y2=y1+wfont[d_f].fh[ct].ymax; 
-         if(minx>x1) minx=x1; if(miny>y1) miny=y1; 
-         if(maxx<x2) maxx=x2; if(maxy<y2) maxy=y2; 
-     } 
-     else { 
-         paintfont(wfont+d_f,cc,dvix-minx,dviy-miny,currentcolor); 
-     } 
-     return cc; 
- } 
-   
- void DVI_set(int p) 
- { 
-     int cc; 
-     cc=DVI_put(p); 
-     if(cc<0) return; 
-     d_h+=wfont[d_f].fh[cc-wfont[d_f].bc].w; 
- } 
-   
- int DVI_put_rule(void) 
- { 
-     int xxx, xx, yy, x1, y1, x2, y2, xx1, xx2, yy1, yy2; 
-     yy=texint(dviptr+1,4); xx=texint(dviptr+5,4); dviptr+=8; 
-     if(xx<=0 || yy<=0) return xx; 
-     xxx=xx; 
-     if(xx>=0) {xx=rint(dviratio*xx+blacker); if(xx>0) xx--;} 
-     else {xx=rint(dviratio*xx-blacker); if(xx<0) xx--;} 
-     if(yy>=0) {yy=rint(dviratio*yy+blacker); if(yy>0) yy--;} 
-     else {yy=rint(dviratio*yy-blacker); if(yy<0) yy--;} 
-     if(pass==1) { 
-         x1=rint(dviratio*d_h); y2=rint(dviratio*d_v); 
-         x2=x1+xx; y1=y2-yy; 
-         if(x1<x2) {xx1=x1; xx2=x2;} else {xx1=x2; xx2=x1;} 
-         if(y1<y2) {yy1=y1; yy2=y2;} else {yy1=y2; yy2=y1;} 
-         if(minx>x1) minx=x1; if(miny>y1) miny=y1; 
-         if(maxx<x2) maxx=x2; if(maxy<y2) maxy=y2; 
-     } 
-     else { 
-         x1=rint(dviratio*d_h)-minx; y1=rint(dviratio*d_v)-miny; 
-         x2=x1+xx; y2=y1-yy; 
-         if(x1<x2) {xx1=x1; xx2=x2;} else {xx1=x2; xx2=x1;} 
-         if(y1<y2) {yy1=y1; yy2=y2;} else {yy1=y2; yy2=y1;} 
-         gdImageFilledRectangle(image,xx1,yy1,xx2,yy2,currentcolor); 
-     } 
-     return xxx; 
- } 
-   
- void DVI_set_rule(void) 
- { 
-     d_h+=DVI_put_rule(); 
- } 
-   
- void DVI_fnt_num(int p) 
- { 
-     int fnum; 
-     if(p==0) fnum=*dviptr-171; else fnum=texint(dviptr+1,p); 
-     dviptr+=p; 
-     for(d_f=0; d_f<fontcnt && wfont[d_f].num!=fnum; d_f++); 
-     if(d_f>=fontcnt) error("Bad dvi: using font before defining it."); 
- } 
-   
- void DVI_fnt_def(int p) 
- { 
-     int i, fnum, fdensity; 
-     char fname[1024]; 
-     unsigned long int c,s,d,a,l; 
-     double fratio; 
-     union { unsigned long c; char C[4]; } U; 
-   
-     if(fontcnt>=FONT_NUMBER_LIMIT) error("Font number exceeded design capacity."); 
-     fnum=texint(++dviptr,p); dviptr+=p; 
-     for (i = 0; i <= 3; i++) U.C[i] = dviptr[i]; 
-     c=U.c; dviptr+=4; 
-     s=texint(dviptr,4); dviptr+=4; 
-     d=texint(dviptr,4); dviptr+=4; 
-     a=*dviptr++; l=*dviptr++; 
-     if(a+l>1000 || a+l<1) error("Bad dvi: bad font name."); 
-     memmove(- fname ,- dviptr ,- a +- l );-  fname [- a +- l ]=0;-  dviptr +=- a +- l -1;
 
-     if(pass==1) { 
-         fdensity=(double) density*((double) s/d); 
-         if(loadfont(fname, c, fdensity, wfont+fontcnt)==NULL) { 
-             if(loadfont("cmr10",0,fdensity,wfont+fontcnt)==NULL) 
-               error("Font panick: even cmr10 cannot be found."); 
-             else fprintf(- stderr ,"Font %s not found; replace by cmr10.\n",- fname );
 
-         } 
-         wfont[fontcnt].num=fnum; 
-         fratio=(double) s/wfont[fontcnt].designsize*d/65536; 
-         for(i=0;i<wfont[fontcnt].cnt; i++) 
-           wfont[fontcnt].fh[i].w=fratio*wfont[fontcnt].fh[i].w; 
-         fontcnt++; 
-     } 
- } 
-   
- void DVI_push(void) 
- { 
-     if(dvistackptr>=DVI_STACK_LIMIT) error("dvi stack overflow."); 
-     dvistack[dvistackptr].h=d_h; 
-     dvistack[dvistackptr].v=d_v; 
-     dvistack[dvistackptr].w=d_w; 
-     dvistack[dvistackptr].x=d_x; 
-     dvistack[dvistackptr].y=d_y; 
-     dvistack[dvistackptr].z=d_z; 
-     dvistackptr++; 
- } 
-   
- void DVI_pop(void) 
- { 
-     if(dvistackptr<=0) error("Bad dvi file: dvi stack underflow."); 
-     dvistackptr--; 
-     d_h=dvistack[dvistackptr].h; 
-     d_v=dvistack[dvistackptr].v; 
-     d_w=dvistack[dvistackptr].w; 
-     d_x=dvistack[dvistackptr].x; 
-     d_y=dvistack[dvistackptr].y; 
-     d_z=dvistack[dvistackptr].z; 
- } 
-   
- void DVI_move(int *hv, int p) 
- { 
-     int t; 
-     t=texintsigned(dviptr+1,p); dviptr+=p; 
-     *hv+=t; 
- } 
-   
- void DVI_move2(int *hv, int *xyz, int p) 
- { 
-     if(p>0) *xyz=texintsigned(dviptr+1,p); 
-     *hv+=*xyz; 
-     dviptr+=p; 
- } 
-   
- void DVI_xxx(int p) 
- { 
-     int i, t; 
-     char *pp, buf[1024]; 
-   
-     t=texint(dviptr+1,p); 
-     if(pass<2 || t>1000) {dviptr+=t+p; return;} 
-     memmove(- buf ,- dviptr +1+1,- t );-  buf [- t ]=0;
 
-     dviptr+=t+p; 
-     for(- i =0;- i <- t ;- i ++)-  buf [- i ]=tolower(- buf [- i ]);
 
-     if(strncmp(- buf ,"color",5)!=0) return;
 
-     pp=find_word_start(buf+5); if(*pp!='=') return; 
-     makecolor(pp+1); 
- } 
-   
-         /* load and interprete dvi file */ 
- void dvi(void) 
- { 
-     unsigned char cc, *startpoint; 
-     char namebuf[1024]; 
-   
-     snprintf(- namebuf ,sizeof(- namebuf ),"%s/texgif.dvi",- tmpdir );
 
-     dvilen=getfile(namebuf,&dvibuf); 
-     if(dvilen<=0) error("dvi file not found."); 
-     dviptr=dvibuf; fontcnt=0; 
-     if(*dviptr++!=dvi_pre || *dviptr++!=2) { 
-         /* baddvi: */ error("Bad dvi file header."); 
-     } 
-     num=texint(dviptr,4); dviptr+=4; 
-     den=texint(dviptr,4); dviptr+=4; 
-     mag=texint(dviptr,4); dviptr+=4; 
-     cc=*dviptr++; dviptr+=cc; startpoint=dviptr; 
-     density=rint((double) compressratio*mag*basedensity/1000); 
-     dviratio=(double) num/den*density/254000; 
- printf("dvi file: num=%d, den=%d, ratio=%f, mag=%d, density=%d\n", 
-        num,den,dviratio, mag, density); 
-     for(pass=1; pass<=2; pass++) { 
-         passstop=0; d_f=-1; pageptr=0; 
-         for(dviptr=startpoint; dviptr<dvibuf+dvilen && passstop>=0; dviptr++) { 
-             if(*dviptr<128) { 
-                 DVI_set(0); continue; 
-             } 
-             if(*dviptr>=171 && *dviptr<=234) { 
-                 DVI_fnt_num(0); continue; 
-             } 
-             switch(*dviptr) { 
-                 case dvi_set1: case dvi_set2: case dvi_set3: 
-                 case dvi_set4: DVI_set(*dviptr-dvi_set1+1); break; 
-                 case dvi_set_rule: DVI_set_rule(); break; 
-   
-                 case dvi_put1: case dvi_put2: case dvi_put3: 
-                 case dvi_put4: DVI_put(*dviptr-dvi_put1+1); break; 
-                 case dvi_put_rule: DVI_put_rule(); break; 
-   
-                 case dvi_nop: DVI_nop(); break; 
-                 case dvi_bop: DVI_bop(); break; 
-                 case dvi_eop: DVI_eop(); break; 
-                 case dvi_push: DVI_push(); break; 
-                 case dvi_pop: DVI_pop(); break; 
-   
-                 case dvi_right1: case dvi_right2: case dvi_right3: 
-                 case dvi_right4: DVI_move(&d_h, *dviptr-dvi_right1+1); break; 
-   
-                 case dvi_w0: case dvi_w1: case dvi_w2: case dvi_w3: 
-                 case dvi_w4: DVI_move2(&d_h, &d_w, *dviptr-dvi_w0); break; 
-                 case dvi_x0: case dvi_x1: case dvi_x2: case dvi_x3: 
-                 case dvi_x4: DVI_move2(&d_h, &d_x, *dviptr-dvi_x0); break; 
-   
-                 case dvi_down1: case dvi_down2: case dvi_down3: 
-                 case dvi_down4: DVI_move(&d_v, *dviptr-dvi_down1+1); break; 
-   
-                 case dvi_y0: case dvi_y1: case dvi_y2: case dvi_y3: 
-                 case dvi_y4: DVI_move2(&d_v, &d_y, *dviptr-dvi_y0); break; 
-                 case dvi_z0: case dvi_z1: case dvi_z2: case dvi_z3: 
-                 case dvi_z4: DVI_move2(&d_v, &d_z, *dviptr-dvi_z0); break; 
-   
-                 case dvi_fnt1: case dvi_fnt2: case dvi_fnt3: 
-                 case dvi_fnt4: DVI_fnt_num(*dviptr-dvi_fnt1+1); break; 
-   
-                 case dvi_xxx1: case dvi_xxx2: case dvi_xxx3: 
-                 case dvi_xxx4: DVI_xxx(*dviptr-dvi_xxx1+1); break; 
-   
-                 case dvi_fnt_def1: case dvi_fnt_def2: case dvi_fnt_def3: 
-                 case dvi_fnt_def4: DVI_fnt_def(*dviptr-dvi_fnt_def1+1); break; 
-   
-                 case dvi_pre: error("Bad dvi file: pre within file."); 
-                 case dvi_post: DVI_post(); break; 
-                 case dvi_post_post: DVI_post_post(); break; 
-   
-                 default: error("Bad dvi file: unknown command."); 
-             } 
-         } 
-     } 
- } 
-   
-