home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Creative Computers
/
CreativeComputers.iso
/
shareware
/
text
/
dvi_3.62
/
source
/
dvisrc.lha
/
dvi.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-08
|
12KB
|
599 lines
/*
** Datei: DVI.C
** Autor: Ingo Eichenseher
** Gerhard Wilhelms, 27.8.92
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stdlib.h>
#include "dvi.h"
#include "dvisplin.h"
#include "dviframe.h"
#include "dvidraw.h"
#include "dvidvi.h"
#include "dvimisc.h"
#include "dvihdcp.h"
/*
** Globale Variablen
*/
static int pixel_width, pixel_height;
static int xoff=0, yoff=0;
static int passes, pass;
static FILE *ship_fp = NULL;
static long huge *ship_pos = NULL, ship_pp;
static size_t ship_pl = 0;
static byte huge *fmem_p = NULL;
static long fmem_s = 0;
static int ship_index;
static jmp_buf stop_jmp;
/*
** Globale externe Variablen
*/
dvi_info_t dvi_info;
const int dvilw = 0;
int frame_width, frame_height, frame_valid = 0;
long frame_size;
char page_string[80];
int y_pass;
FILE *missing = NULL;
char dvi_name[128];
int (*shipout)(void) = NULL;
double aspect_ratio;
char ship_name[128] = "";
FILE *red_fp = NULL;
options op =
{
0l, /* Magic */
101, 101, /* Aufloesung */
0, 0, /* Seitenbreite und Hoehe */
0, 0, 0, 0, /* Raender */
0, 0, /* Druckraender */
0.5, /* IMG-Dichte */
0, /* mag */
1, /* copies */
#ifndef AMIGA
0, /* Nummer des Ausgabegeraets */
#else
-1, /* kein Ausgabegeraet */
#endif
1,1,1,0,0,0,0,0,0,1,0,0, /* Verschiedene Flags */
0, /* Biosdev */
0l, 0l, 0l, /* pixmem, maxmem, pathmem */
"","","","",
PK_FULLNAME, /* Default falls PK_FULLCONFIG, sonst "" */
#ifdef AMIGA
"", /* callmf */
#endif
"","","", /* Pfade */
};
int null_device(void)
{
return 0;
}
static void ship_finit(int pages)
{
if (ship_name[0]=='\0') exgext(ship_name,dvi_name,SHIPEXT);
ship_fp = fopen(ship_name,"wb");
if (ship_fp==NULL)
halt("Cannot open output-file %s",ship_name);
fwrite(&frame_width,sizeof(int),1,ship_fp);
fwrite(&pixel_height,sizeof(int),1,ship_fp);
ship_pp = 2*sizeof(int);
ship_index = 0;
ship_pl = pages*sizeof(long);
if (op.tracemem) xprint(0,"{Ship:%ld",(long)ship_pl);
ship_pos = mem_alloc(ship_pl,"Ship-Positions");
}
static void ship_fexit(void)
{
if (ship_fp!=NULL)
{
fwrite((void*)ship_pos,sizeof(long),ship_index,ship_fp);
fwrite(&ship_index,sizeof(int),1,ship_fp);
fwrite(&ship_pp,sizeof(long),1,ship_fp);
fclose(ship_fp);
ship_fp = NULL;
print("Pixel output written on %s",ship_name);
}
if (ship_pos!=NULL)
{
mem_free(ship_pos,ship_pl);
if (op.tracemem) xprint(-1,"}");
ship_pos = NULL;
}
}
static void red_init(void)
{
if (red_fp!=NULL)
{
fclose(red_fp);
red_fp = NULL;
}
if (*op.redirect)
{
red_fp = fopen(op.redirect,"wb");
if (red_fp==NULL) halt("Cannot open file %s for write",op.redirect);
}
}
static void red_exit(void)
{
if (red_fp!=NULL)
{
fclose(red_fp);
red_fp = NULL;
}
}
int shipfile(void)
{
long p = 0;
long s, height;
int rep = 0;
if (ship_fp==NULL)
halt("Internal error: output file not open");
height=frame_height;
if (height>pixel_height-y_pass) height=pixel_height-y_pass;
for(s=height*(long)frame_width; s--; p++)
{
if (frame_get(p))
{
if (rep)
{
putc(0,ship_fp);
putc(rep,ship_fp);
ship_pp += 2;
rep = 0;
}
putc(frame_get(p),ship_fp);
ship_pp++;
}
else
{
if (rep==255)
{
putc(0,ship_fp);
putc(rep,ship_fp);
ship_pp += 2;
rep = 0;
}
rep++;
}
}
if (rep)
{
putc(0,ship_fp);
putc(rep,ship_fp);
ship_pp += 2;
}
return 0;
}
#ifdef __TURBOC__
#pragma warn -par
#endif
void other_special(int x, int y)
{
}
void psfont_def(fnt_t *f, double size)
{
}
int resident(fnt_t *f)
{
return 0;
}
void do_resident_char(long cc, pos *p)
{
}
#ifdef __TURBOC__
#pragma warn .par
#endif
static long frame_init(void)
{
long full_size;
int fhmax, xs, ys;
frame_valid = 0;
fmem_s = frame_max();
xoff = iround(op.hoffset*op.hres);
yoff = iround(op.voffset*op.vres);
xs = iround(op.hspread*op.hres);
ys = iround(op.vspread*op.vres);
if (op.width==0 || op.height==0)
{
pixel_width = dvi_info.width + xoff + xs;
pixel_height = dvi_info.height + yoff + ys;
}
else
{
pixel_width = iround(ceil(op.width*op.hres)) + xs + xoff;
pixel_height = iround(ceil(op.height*op.vres)) + ys + yoff;
}
if (op.landscape)
{
int h=pixel_width; pixel_width=pixel_height; pixel_height=h;
}
frame_width = (pixel_width+7) / 8;
if (frame_width&1) frame_width++;
#ifdef apollo
if (frame_width&2) frame_width += 2;
#endif
frame_height = pixel_height;
full_size = (long)frame_width * (long)(frame_height+MAX_PINS);
if (fmem_s==0 || fmem_s>full_size)
{
fmem_s = full_size;
passes = 1;
}
else
{
fhmax = (int)(fmem_s/(long)frame_width) - MAX_PINS;
if (fhmax<MAX_PINS) halt("Not enough memory for scan lines");
passes = (int)(((long)frame_height+(long)fhmax-1l)/(long)fhmax);
if (frame_height>fhmax) frame_height = fhmax;
}
frame_size = (long)frame_width * (long)(frame_height+MAX_PINS);
fmem_s = frame_size;
if (op.tracemem) xprint(0,"{BitMap:%ld",fmem_s);
fmem_p = frame_alloc(fmem_s);
frame_set(fmem_p,fmem_s);
setframe(frame_width,frame_height);
return full_size;
}
void do_bop(long ll[10])
{
char *s;
s = fmt_page(ll);
if (passes<2) xprint(3,"[%s",s);
else xprint(3,"[%s.%c",s,pass+'a');
strcpy(page_string,s);
gr_defaults();
}
void do_eop(int char_missing)
{
if (char_missing) xprint(-1,"*]");
else xprint(-1,"]");
}
void end_string(void)
{
}
void do_pkchar(pk_char *c, pos *p)
{
if (op.landscape)
{
if (clip_active)
ldraw2_char(c,pixel_width-((int)p->vv+yoff),
(int)p->hh-y_pass+xoff);
else
ldraw_char(c,pixel_width-((int)p->vv+yoff),
(int)p->hh-y_pass+xoff);
}
else
{
if (clip_active)
draw2_char(c,(int)p->hh+xoff,(int)p->vv-y_pass+yoff);
else
draw_char(c,(int)p->hh+xoff,(int)p->vv-y_pass+yoff);
}
}
void do_rule(pos *p, long width, long height)
{
if (op.landscape)
if (clip_active)
draw2_rule(pixel_width-((int)p->vv+yoff),
(int)(p->hh)+xoff-y_pass, (int)height,(int)width);
else
draw_rule(pixel_width-((int)p->vv+yoff),
(int)(p->hh)+xoff-y_pass, (int)height,(int)width);
else
if (clip_active)
draw2_rule((int)p->hh+xoff, (int)(p->vv-height+1)-y_pass+yoff,
(int)width,(int)height);
else
draw_rule((int)p->hh+xoff, (int)(p->vv-height+1)-y_pass+yoff,
(int)width,(int)height);
}
void do_font(fnt_t *f)
{
fnt_select(f);
}
void do_special(long len, pos *p)
{
if (op.landscape)
special(len,pixel_width-((int)p->vv+yoff),(int)(p->hh)+xoff-y_pass);
else
special(len,(int)p->hh+xoff,(int)p->vv-y_pass+yoff);
}
/*
** ------------------------------------------------------------------
** hardcopy routines
** ------------------------------------------------------------------
*/
/*
** -------------- machine independent hardcopy routines -------------
*/
static void minmax(int *min,
register int *max,
register int huge *addr,
register int words)
{
register int i;
for (i=0; i<words && *addr==0; i++,addr++);
*min = *max = i;
for (; i<words; i++) if (*addr++) *max=i+1;
}
int print_page
(
int pins,
void (*skip_lines)(int amount),
int (*send_lines)(long addr, int words, int width, int pos),
void (*init_page)(void),
void (*exit_page)(void)
)
{
int min,max,minpins,maxpins,skip,height;
register int y=0,i;
register long addr = 0l, addr1;
if (pass==0)
{
(*init_page)();
skip=iround(op.vmargin*op.vres);
}
else skip=0;
height=frame_height;
if (height>pixel_height-y_pass) height=pixel_height-y_pass;
while(y<height)
{
while(y<height)
{
minmax(&min,&max,(int huge *)frame_ptr(addr),frame_width/2);
if (min<max) break;
skip++; y++;
addr += frame_width;
}
if (y>=height) break;
if (skip>0) (*skip_lines)(skip);
minpins=min; maxpins=max; addr1=addr+frame_width;
for (i=1; i<pins && i<height-y; i++)
{
minmax(&min,&max,(int huge *)frame_ptr(addr1),frame_width/2);
addr1 += frame_width;
if (min<max)
{
if (min<minpins) minpins=min;
if (max>maxpins) maxpins=max;
}
}
if ((skip=height-y)>pins) skip=pins;
skip-=(*send_lines)(addr+minpins*2,maxpins-minpins,frame_width,
minpins*16+iround(op.hres*op.hmargin));
if (stop_key())
{
(*exit_page)();
return 1;
}
addr += pins * frame_width;
y += pins;
}
if (skip>0) (*skip_lines)(skip);
if (pass==passes-1)(*exit_page)();
return 0;
}
int get_bound(char *s, long *p)
{
int i=0;
while(*s && i++<10)
{
if (*s=='*')
{
*p++ = ASTERISK;
s++;
}
else
{
char *t=s; int ok=0;
if (*t=='-' || *t=='+') t++;
while(isdigit(*t)) { t++; ok=1; }
if (!ok) return 0;
*p++=atol(s);
s=t;
}
if (*s=='\0') return 1;
if (*s!=',') return 0;
s++;
}
return *s=='\0';
}
/*
** ------------------------------------------------------------------
** the main formatting routines
** ------------------------------------------------------------------
*/
void load_dvi(void)
{
dvi_clean();
catfe(dvi_name,dvi_name,"dvi");
if (dvi_finit(dvi_name,op.dvi_path))
halt("Cannot open DVI file %s",dvi_name);
dvi_fpost(&dvi_info,op.new_mag);
frame_init();
gr_init(dvi_info.mag,dvi_info.orig);
if (op.thin_out) thin_init();
dvi_info.valid = 1;
}
void fmt_stop(void)
{
if (stop_jmp!=NULL && stop_key())
{
xprint(0,"Stopped.");
dvi_clean();
longjmp(stop_jmp,0);
}
}
int format_pages(int first, int last, int step)
{
int ret=0, page, cop, copies;
if (setjmp(stop_jmp)) return ret;
if (!dvi_info.valid) load_dvi();
if (shipout==shipfile) ship_finit(dvi_info.pages);
red_init();
copies = shipout==NULL || shipout==shipfile ? 1:op.copies;
for (page=first; (page<=last && step>0) || (page>=last && step<0); page+=step)
{
long this_page;
if (page<1 || page>dvi_info.pages) continue;
this_page = dvi_info.table[page-1];
if (shipout==shipfile)
{
if (ship_index>=dvi_info.pages)
halt("Internal Error: too much pages in file");
ship_pos[ship_index++] = ship_pp;
}
for (cop=0; cop<copies; cop++)
for (pass=0, y_pass=0; pass<passes; pass++, y_pass+=frame_height)
{
frame_clr();
clip_clean(1);
if (dvi_fseek(this_page))
halt("Cannot seek to page in dvi-file");
if (setjmp(stop_jmp))
{
memset(stop_jmp,0,sizeof(stop_jmp));
red_exit();
return ret;
}
else if (do_page((pos*)NULL,&dvi_info.fonts,
dvi_info.hconv,dvi_info.vconv,0,NULL,NULL)<0)
{
if (shipout==shipfile) ship_index--;
cop = copies;
break;
}
ret = page;
frame_valid = 1;
if (op.singlesheet && shipout!=shipfile && shipout!=NULL)
if (wait_for_sheet()) return ret;
if (op.thin_out)
{
thin_out(frame_height>pixel_height-y_pass ?
pixel_height-y_pass : frame_height, frame_width);
}
if (shipout!=NULL && (*shipout)())
{
xprint(0,"Stopped.");
ship_fexit();
red_exit();
return ret;
}
}
}
ship_fexit();
red_exit();
return ret;
}
void dvi_clean(void)
{
dvi_info.valid = 0;
frame_valid = 0;
if (missing!=NULL)
{
print("Info for missing fonts written on %s",MISSING);
fclose(missing);
missing = NULL;
}
clip_clean(1);
ship_fexit();
red_exit();
if (fmem_p!=NULL)
{
frame_free(fmem_p,fmem_s);
if (op.tracemem) xprint(-1,"}");
fmem_p = NULL;
}
if (dvi_info.table!=NULL)
{
mem_free(dvi_info.table,dvi_info.pages*sizeof(long));
if (op.tracemem) xprint(-1,"}");
}
fnt_lfree(dvi_info.fonts);
dvi_info.fonts = NULL;
dvi_info.table = NULL;
dvi_fexit();
mem_test();
}