Subversion Repositories wimsdev

Rev

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

  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.  */
  17. #include "texgif.h"
  18.  
  19. /* dvi 2 gif driver, dvi interpreter */
  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
  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;
  135.         if(maxx<=minx || maxy<=miny) texgif_error("Empty page.");
  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;
  148.     if(d_f<0) texgif_error("Bad dvi: trying to put non-existing font.");
  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;
  157.         if(minx>x1) minx=x1;
  158.         if(miny>y1) miny=y1;
  159.         if(maxx<x2) maxx=x2;
  160.         if(maxy<y2) maxy=y2;
  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;}
  191.         if(minx>x1) minx=x1;
  192.         if(miny>y1) miny=y1;
  193.         if(maxx<x2) maxx=x2;
  194.         if(maxy<y2) maxy=y2;
  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++);
  217.     if(d_f>=fontcnt) texgif_error("Bad dvi: using font before defining it.");
  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.  
  228.     if(fontcnt>=FONT_NUMBER_LIMIT) texgif_error("Font number exceeded design capacity.");
  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++;
  235.     if(a+l>1000 || a+l<1) texgif_error("Bad dvi: bad font name.");
  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) {
  240.             if(loadfont("cmr10",0,fdensity,wfont+fontcnt)==NULL)
  241.               texgif_error("Font panick: even cmr10 cannot be found.");
  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. {
  254.     if(dvistackptr>=DVI_STACK_LIMIT) texgif_error("dvi stack overflow.");
  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. {
  266.     if(dvistackptr<=0) texgif_error("Bad dvi file: dvi stack underflow.");
  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];
  294.  
  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];
  310.  
  311.     snprintf(namebuf,sizeof(namebuf),"%s/texgif.dvi",tmpdir);
  312.     dvilen=getfile(namebuf,&dvibuf);
  313.     if(dvilen<=0) texgif_error("dvi file not found.");
  314.     dviptr=dvibuf; fontcnt=0;
  315.     if(*dviptr++!=dvi_pre || *dviptr++!=2) {
  316.         /* baddvi: */ texgif_error("Bad dvi file header.");
  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;
  339.  
  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;
  343.  
  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;
  349.  
  350.                 case dvi_right1: case dvi_right2: case dvi_right3:
  351.                 case dvi_right4: DVI_move(&d_h, *dviptr-dvi_right1+1); break;
  352.  
  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;
  357.  
  358.                 case dvi_down1: case dvi_down2: case dvi_down3:
  359.                 case dvi_down4: DVI_move(&d_v, *dviptr-dvi_down1+1); break;
  360.  
  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;
  365.  
  366.                 case dvi_fnt1: case dvi_fnt2: case dvi_fnt3:
  367.                 case dvi_fnt4: DVI_fnt_num(*dviptr-dvi_fnt1+1); break;
  368.  
  369.                 case dvi_xxx1: case dvi_xxx2: case dvi_xxx3:
  370.                 case dvi_xxx4: DVI_xxx(*dviptr-dvi_xxx1+1); break;
  371.  
  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;
  374.  
  375.                 case dvi_pre: texgif_error("Bad dvi file: pre within file.");
  376.                 case dvi_post: DVI_post(); break;
  377.                 case dvi_post_post: DVI_post_post(); break;
  378.  
  379.                 default: texgif_error("Bad dvi file: unknown command.");
  380.             }
  381.         }
  382.     }
  383.     free(dvibuf);
  384. }
  385.  
  386.