home *** CD-ROM | disk | FTP | other *** search
/ Creative Computers / CreativeComputers.iso / shareware / text / dvi_3.62 / source / dvisrc.lha / dvi.c < prev    next >
C/C++ Source or Header  |  1993-11-08  |  12KB  |  599 lines

  1. /*
  2. ** Datei: DVI.C
  3. ** Autor: Ingo Eichenseher
  4. **        Gerhard Wilhelms, 27.8.92
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include <math.h>
  11. #include <setjmp.h>
  12. #include <stdarg.h>
  13. #include <stdlib.h>
  14.  
  15. #include "dvi.h"
  16. #include "dvisplin.h"
  17. #include "dviframe.h"
  18. #include "dvidraw.h"
  19. #include "dvidvi.h"
  20. #include "dvimisc.h"
  21. #include "dvihdcp.h"
  22.  
  23.  
  24. /*
  25. ** Globale Variablen
  26. */
  27.  
  28. static int          pixel_width, pixel_height;
  29. static int          xoff=0, yoff=0;
  30. static int          passes, pass;
  31. static FILE        *ship_fp = NULL;
  32. static long huge   *ship_pos = NULL, ship_pp;
  33. static size_t       ship_pl = 0;
  34. static byte huge   *fmem_p = NULL;
  35. static long         fmem_s = 0;
  36. static int          ship_index;
  37. static jmp_buf      stop_jmp;
  38.  
  39. /*
  40. ** Globale externe Variablen
  41. */
  42.  
  43. dvi_info_t  dvi_info;
  44. const int   dvilw = 0;
  45. int         frame_width, frame_height, frame_valid = 0;
  46. long        frame_size;
  47.  
  48. char        page_string[80];
  49. int         y_pass;
  50. FILE       *missing = NULL;
  51. char        dvi_name[128];
  52. int         (*shipout)(void) = NULL;
  53. double      aspect_ratio;
  54. char        ship_name[128] = "";
  55.  
  56. FILE        *red_fp = NULL;
  57.  
  58. options     op =
  59. {
  60.     0l,                         /* Magic */
  61.     101, 101,                   /* Aufloesung */
  62.     0, 0,                       /* Seitenbreite und Hoehe */
  63.     0, 0, 0, 0,                 /* Raender */
  64.     0, 0,                       /* Druckraender */
  65.     0.5,                        /* IMG-Dichte */
  66.     0,                          /* mag */
  67.     1,                          /* copies */
  68. #ifndef AMIGA
  69.     0,                          /* Nummer des Ausgabegeraets */
  70. #else
  71.     -1,                         /* kein Ausgabegeraet */
  72. #endif
  73.     1,1,1,0,0,0,0,0,0,1,0,0,    /* Verschiedene Flags */
  74.     0,                          /* Biosdev */
  75.     0l, 0l, 0l,                 /* pixmem, maxmem, pathmem */
  76.     "","","","",
  77.     PK_FULLNAME,                /* Default falls PK_FULLCONFIG, sonst "" */
  78. #ifdef AMIGA
  79.     "",                         /* callmf */
  80. #endif
  81.     "","","",                   /* Pfade */
  82. };
  83.  
  84. int null_device(void)
  85. {
  86.     return 0;
  87. }
  88.  
  89. static void ship_finit(int pages)
  90. {
  91.     if (ship_name[0]=='\0') exgext(ship_name,dvi_name,SHIPEXT);
  92.     ship_fp = fopen(ship_name,"wb");
  93.     if (ship_fp==NULL)
  94.     halt("Cannot open output-file %s",ship_name);
  95.     fwrite(&frame_width,sizeof(int),1,ship_fp);
  96.     fwrite(&pixel_height,sizeof(int),1,ship_fp);
  97.     ship_pp = 2*sizeof(int);
  98.     ship_index = 0;
  99.     ship_pl = pages*sizeof(long);
  100.     if (op.tracemem) xprint(0,"{Ship:%ld",(long)ship_pl);
  101.     ship_pos = mem_alloc(ship_pl,"Ship-Positions");
  102. }
  103.  
  104. static void ship_fexit(void)
  105. {
  106.     if (ship_fp!=NULL)
  107.     {
  108.     fwrite((void*)ship_pos,sizeof(long),ship_index,ship_fp);
  109.     fwrite(&ship_index,sizeof(int),1,ship_fp);
  110.     fwrite(&ship_pp,sizeof(long),1,ship_fp);
  111.     fclose(ship_fp);
  112.     ship_fp = NULL;
  113.     print("Pixel output written on %s",ship_name);
  114.     }
  115.     if (ship_pos!=NULL)
  116.     {
  117.     mem_free(ship_pos,ship_pl);
  118.     if (op.tracemem) xprint(-1,"}");
  119.     ship_pos = NULL;
  120.     }
  121. }
  122.  
  123. static void red_init(void)
  124. {
  125.     if (red_fp!=NULL) 
  126.     {
  127.     fclose(red_fp);
  128.     red_fp = NULL;
  129.     }
  130.     if (*op.redirect)
  131.     {
  132.     red_fp = fopen(op.redirect,"wb");
  133.     if (red_fp==NULL) halt("Cannot open file %s for write",op.redirect);
  134.     }
  135. }
  136.  
  137. static void red_exit(void)
  138. {
  139.     if (red_fp!=NULL) 
  140.     {
  141.     fclose(red_fp);
  142.     red_fp = NULL;
  143.     }
  144. }
  145.  
  146. int shipfile(void)
  147. {
  148.     long  p = 0;
  149.     long  s, height;
  150.     int   rep = 0;
  151.  
  152.     if (ship_fp==NULL)
  153.     halt("Internal error: output file not open");
  154.  
  155.     height=frame_height;
  156.     if (height>pixel_height-y_pass) height=pixel_height-y_pass;
  157.     for(s=height*(long)frame_width; s--; p++)
  158.     {
  159.     if (frame_get(p))
  160.     {
  161.         if (rep)
  162.         {
  163.         putc(0,ship_fp);
  164.         putc(rep,ship_fp);
  165.         ship_pp += 2;
  166.         rep = 0;
  167.         }
  168.         putc(frame_get(p),ship_fp);
  169.         ship_pp++;
  170.     }
  171.     else
  172.     {
  173.         if (rep==255)
  174.         {
  175.         putc(0,ship_fp);
  176.         putc(rep,ship_fp);
  177.         ship_pp += 2;
  178.         rep = 0;
  179.         }
  180.         rep++;
  181.     }
  182.     }
  183.     if (rep)
  184.     {
  185.     putc(0,ship_fp);
  186.     putc(rep,ship_fp);
  187.     ship_pp += 2;
  188.     }
  189.     return 0;
  190. }
  191.  
  192. #ifdef __TURBOC__
  193. #pragma warn -par
  194. #endif
  195.  
  196. void other_special(int x, int y)
  197. {
  198. }
  199.  
  200. void psfont_def(fnt_t *f, double size)
  201. {
  202. }
  203.  
  204. int resident(fnt_t *f)
  205. {
  206.     return 0;
  207. }
  208.  
  209. void do_resident_char(long cc, pos *p)
  210. {
  211. }
  212.  
  213. #ifdef __TURBOC__
  214. #pragma warn .par
  215. #endif
  216.  
  217. static long frame_init(void)
  218. {
  219.     long full_size;
  220.     int  fhmax, xs, ys;
  221.  
  222.     frame_valid = 0;
  223.  
  224.     fmem_s = frame_max();
  225.  
  226.     xoff = iround(op.hoffset*op.hres);
  227.     yoff = iround(op.voffset*op.vres);
  228.     xs   = iround(op.hspread*op.hres);
  229.     ys   = iround(op.vspread*op.vres);
  230.  
  231.     if (op.width==0 || op.height==0)
  232.     {
  233.     pixel_width = dvi_info.width + xoff + xs;
  234.     pixel_height = dvi_info.height + yoff + ys;
  235.     }
  236.     else
  237.     {
  238.     pixel_width =  iround(ceil(op.width*op.hres)) + xs + xoff;
  239.     pixel_height = iround(ceil(op.height*op.vres)) + ys + yoff;
  240.     }
  241.  
  242.     if (op.landscape)
  243.     {
  244.     int h=pixel_width; pixel_width=pixel_height; pixel_height=h;
  245.     }
  246.  
  247.     frame_width = (pixel_width+7) / 8;
  248.     if (frame_width&1) frame_width++;
  249. #ifdef apollo
  250.     if (frame_width&2) frame_width += 2;
  251. #endif
  252.     frame_height = pixel_height;
  253.  
  254.     full_size = (long)frame_width * (long)(frame_height+MAX_PINS);
  255.  
  256.     if (fmem_s==0 || fmem_s>full_size)
  257.     {
  258.     fmem_s = full_size;
  259.     passes = 1;
  260.     }
  261.     else
  262.     {
  263.     fhmax = (int)(fmem_s/(long)frame_width) - MAX_PINS;
  264.     if (fhmax<MAX_PINS) halt("Not enough memory for scan lines");
  265.     passes = (int)(((long)frame_height+(long)fhmax-1l)/(long)fhmax);
  266.     if (frame_height>fhmax) frame_height = fhmax;
  267.     }
  268.  
  269.     frame_size = (long)frame_width * (long)(frame_height+MAX_PINS);
  270.     fmem_s = frame_size;
  271.  
  272.     if (op.tracemem) xprint(0,"{BitMap:%ld",fmem_s);
  273.     fmem_p = frame_alloc(fmem_s);
  274.     frame_set(fmem_p,fmem_s);
  275.     setframe(frame_width,frame_height);
  276.  
  277.     return full_size;
  278. }
  279.  
  280. void do_bop(long ll[10])
  281. {
  282.     char *s;
  283.     s = fmt_page(ll);
  284.     if (passes<2) xprint(3,"[%s",s);
  285.     else xprint(3,"[%s.%c",s,pass+'a');
  286.     strcpy(page_string,s);
  287.     gr_defaults();
  288. }
  289.  
  290. void do_eop(int char_missing)
  291. {
  292.     if (char_missing) xprint(-1,"*]");
  293.     else xprint(-1,"]");
  294. }
  295.  
  296. void end_string(void)
  297. {
  298. }
  299.  
  300. void do_pkchar(pk_char *c, pos *p)
  301. {
  302.     if (op.landscape)
  303.     {
  304.     if (clip_active)
  305.         ldraw2_char(c,pixel_width-((int)p->vv+yoff),
  306.             (int)p->hh-y_pass+xoff);
  307.     else
  308.         ldraw_char(c,pixel_width-((int)p->vv+yoff),
  309.                (int)p->hh-y_pass+xoff);
  310.     }
  311.     else
  312.     {
  313.     if (clip_active)
  314.         draw2_char(c,(int)p->hh+xoff,(int)p->vv-y_pass+yoff);
  315.     else
  316.         draw_char(c,(int)p->hh+xoff,(int)p->vv-y_pass+yoff);
  317.     }
  318. }
  319.  
  320. void do_rule(pos *p, long width, long height)
  321. {
  322.     if (op.landscape)
  323.     if (clip_active)
  324.         draw2_rule(pixel_width-((int)p->vv+yoff),
  325.           (int)(p->hh)+xoff-y_pass, (int)height,(int)width);
  326.     else
  327.         draw_rule(pixel_width-((int)p->vv+yoff),
  328.           (int)(p->hh)+xoff-y_pass, (int)height,(int)width);
  329.     else
  330.     if (clip_active)
  331.         draw2_rule((int)p->hh+xoff, (int)(p->vv-height+1)-y_pass+yoff,
  332.         (int)width,(int)height);
  333.     else
  334.         draw_rule((int)p->hh+xoff, (int)(p->vv-height+1)-y_pass+yoff,
  335.         (int)width,(int)height);
  336. }
  337.  
  338. void do_font(fnt_t *f)
  339. {
  340.     fnt_select(f);
  341. }
  342.  
  343. void do_special(long len, pos *p)
  344. {
  345.     if (op.landscape)
  346.     special(len,pixel_width-((int)p->vv+yoff),(int)(p->hh)+xoff-y_pass);
  347.     else
  348.     special(len,(int)p->hh+xoff,(int)p->vv-y_pass+yoff);
  349. }
  350.  
  351. /*
  352. ** ------------------------------------------------------------------
  353. ** hardcopy routines
  354. ** ------------------------------------------------------------------
  355. */
  356.  
  357. /*
  358. ** -------------- machine independent hardcopy routines -------------
  359. */
  360.  
  361. static void minmax(int *min,
  362.         register int *max,
  363.         register int huge *addr,
  364.         register int words)
  365. {
  366.     register int i;
  367.     for (i=0; i<words && *addr==0; i++,addr++);
  368.     *min = *max = i;
  369.     for (; i<words; i++) if (*addr++) *max=i+1;
  370. }
  371.  
  372. int print_page
  373. (
  374.     int   pins,
  375.     void (*skip_lines)(int amount),
  376.     int  (*send_lines)(long addr, int words, int width, int pos),
  377.     void (*init_page)(void),
  378.     void (*exit_page)(void)
  379. )
  380. {
  381.  
  382.     int      min,max,minpins,maxpins,skip,height;
  383.     register int    y=0,i;
  384.     register long addr = 0l, addr1;
  385.  
  386.     if (pass==0)
  387.     {
  388.     (*init_page)();
  389.     skip=iround(op.vmargin*op.vres);
  390.     }
  391.     else skip=0;
  392.     height=frame_height;
  393.     if (height>pixel_height-y_pass) height=pixel_height-y_pass;
  394.     while(y<height)
  395.     {
  396.     while(y<height)
  397.     {
  398.         minmax(&min,&max,(int huge *)frame_ptr(addr),frame_width/2);
  399.         if (min<max) break;
  400.         skip++; y++;
  401.         addr += frame_width;
  402.     }
  403.     if (y>=height) break;
  404.     if (skip>0) (*skip_lines)(skip);
  405.  
  406.     minpins=min; maxpins=max; addr1=addr+frame_width;
  407.     for (i=1; i<pins && i<height-y; i++)
  408.     {
  409.         minmax(&min,&max,(int huge *)frame_ptr(addr1),frame_width/2);
  410.         addr1 += frame_width;
  411.         if (min<max)
  412.         {
  413.         if (min<minpins) minpins=min;
  414.         if (max>maxpins) maxpins=max;
  415.         }
  416.     }
  417.  
  418.     if ((skip=height-y)>pins) skip=pins;
  419.     skip-=(*send_lines)(addr+minpins*2,maxpins-minpins,frame_width,
  420.                 minpins*16+iround(op.hres*op.hmargin));
  421.  
  422.     if (stop_key())
  423.     {
  424.         (*exit_page)();
  425.         return 1;
  426.     }
  427.  
  428.     addr += pins * frame_width;
  429.     y += pins;
  430.     }
  431.     if (skip>0) (*skip_lines)(skip);
  432.     if (pass==passes-1)(*exit_page)();
  433.     return 0;
  434. }
  435.  
  436.  
  437. int get_bound(char *s, long *p)
  438. {
  439.     int i=0;
  440.     while(*s && i++<10)
  441.     {
  442.     if (*s=='*')
  443.     {
  444.         *p++ = ASTERISK;
  445.         s++;
  446.     }
  447.     else
  448.     {
  449.         char *t=s; int ok=0;
  450.         if (*t=='-' || *t=='+') t++;
  451.         while(isdigit(*t)) { t++; ok=1; }
  452.         if (!ok) return 0;
  453.         *p++=atol(s);
  454.         s=t;
  455.     }
  456.     if (*s=='\0') return 1;
  457.     if (*s!=',') return 0;
  458.     s++;
  459.     }
  460.     return *s=='\0';
  461. }
  462.  
  463. /*
  464. ** ------------------------------------------------------------------
  465. ** the main formatting routines
  466. ** ------------------------------------------------------------------
  467. */
  468.  
  469. void load_dvi(void)
  470. {
  471.     dvi_clean();
  472.  
  473.     catfe(dvi_name,dvi_name,"dvi");
  474.     if (dvi_finit(dvi_name,op.dvi_path)) 
  475.     halt("Cannot open DVI file %s",dvi_name);
  476.     dvi_fpost(&dvi_info,op.new_mag);
  477.     frame_init();
  478.     gr_init(dvi_info.mag,dvi_info.orig);
  479.     if (op.thin_out) thin_init();
  480.     dvi_info.valid = 1;
  481. }
  482.  
  483. void fmt_stop(void)
  484. {
  485.     if (stop_jmp!=NULL && stop_key())
  486.     {
  487.     xprint(0,"Stopped.");
  488.     dvi_clean();
  489.     longjmp(stop_jmp,0);
  490.     }
  491. }
  492.  
  493. int format_pages(int first, int last, int step)
  494. {
  495.     int ret=0, page, cop, copies;
  496.  
  497.     if (setjmp(stop_jmp)) return ret;
  498.  
  499.     if (!dvi_info.valid) load_dvi();
  500.  
  501.     if (shipout==shipfile) ship_finit(dvi_info.pages);
  502.     red_init();
  503.     copies = shipout==NULL || shipout==shipfile ? 1:op.copies;
  504.  
  505.     for (page=first; (page<=last && step>0) || (page>=last && step<0); page+=step)
  506.     {
  507.     long this_page;
  508.  
  509.     if (page<1 || page>dvi_info.pages) continue;
  510.     this_page = dvi_info.table[page-1];
  511.  
  512.     if (shipout==shipfile)
  513.     {
  514.         if (ship_index>=dvi_info.pages)
  515.         halt("Internal Error: too much pages in file");
  516.         ship_pos[ship_index++] = ship_pp;
  517.     }
  518.     for (cop=0; cop<copies; cop++)
  519.         for (pass=0, y_pass=0; pass<passes; pass++, y_pass+=frame_height)
  520.         {
  521.         frame_clr();
  522.         clip_clean(1);
  523.  
  524.         if (dvi_fseek(this_page))
  525.             halt("Cannot seek to page in dvi-file");
  526.  
  527.         if (setjmp(stop_jmp))
  528.         {
  529.             memset(stop_jmp,0,sizeof(stop_jmp));
  530.             red_exit();
  531.             return ret;
  532.         }
  533.         else if (do_page((pos*)NULL,&dvi_info.fonts,
  534.             dvi_info.hconv,dvi_info.vconv,0,NULL,NULL)<0)
  535.         {
  536.             if (shipout==shipfile) ship_index--;
  537.             cop = copies;
  538.             break;
  539.         }
  540.  
  541.         ret = page;
  542.     frame_valid = 1;
  543.  
  544.         if (op.singlesheet && shipout!=shipfile && shipout!=NULL)
  545.             if (wait_for_sheet()) return ret;
  546.  
  547.         if (op.thin_out)
  548.         {
  549.             thin_out(frame_height>pixel_height-y_pass ?
  550.             pixel_height-y_pass : frame_height, frame_width);
  551.         }
  552.  
  553.         if (shipout!=NULL && (*shipout)())
  554.         {
  555.             xprint(0,"Stopped.");
  556.             ship_fexit();
  557.             red_exit();
  558.             return ret;
  559.         }
  560.         }
  561.     }
  562.     ship_fexit();
  563.     red_exit();
  564.     return ret;
  565. }
  566.  
  567. void dvi_clean(void)
  568. {
  569.     dvi_info.valid = 0;
  570.     frame_valid = 0;
  571.  
  572.     if (missing!=NULL)
  573.     {
  574.     print("Info for missing fonts written on %s",MISSING);
  575.     fclose(missing);
  576.     missing = NULL;
  577.     }
  578.  
  579.     clip_clean(1);
  580.     ship_fexit();
  581.     red_exit();
  582.     if (fmem_p!=NULL)
  583.     {
  584.     frame_free(fmem_p,fmem_s);
  585.     if (op.tracemem) xprint(-1,"}");
  586.     fmem_p = NULL;
  587.     }
  588.     if (dvi_info.table!=NULL)
  589.     {
  590.     mem_free(dvi_info.table,dvi_info.pages*sizeof(long));
  591.     if (op.tracemem) xprint(-1,"}");
  592.     }
  593.     fnt_lfree(dvi_info.fonts);
  594.     dvi_info.fonts = NULL;
  595.     dvi_info.table = NULL;
  596.     dvi_fexit();
  597.     mem_test();
  598. }
  599.