summaryrefslogtreecommitdiff
path: root/systems/msdos/emtex-contrib/dvimfj/dvimfj.src/dvimfj.c
diff options
context:
space:
mode:
Diffstat (limited to 'systems/msdos/emtex-contrib/dvimfj/dvimfj.src/dvimfj.c')
-rw-r--r--systems/msdos/emtex-contrib/dvimfj/dvimfj.src/dvimfj.c631
1 files changed, 631 insertions, 0 deletions
diff --git a/systems/msdos/emtex-contrib/dvimfj/dvimfj.src/dvimfj.c b/systems/msdos/emtex-contrib/dvimfj/dvimfj.src/dvimfj.c
new file mode 100644
index 0000000000..56bff96a58
--- /dev/null
+++ b/systems/msdos/emtex-contrib/dvimfj/dvimfj.src/dvimfj.c
@@ -0,0 +1,631 @@
+/*****************************************************************************/
+/* */
+/* dvimfj --- generates an MFJOB program from a .dvi file. */
+/* */
+/*****************************************************************************/
+
+#include <stdio.h>
+#include <ctype.h>
+#include "commands.h"
+#if defined(MSDOS)
+ #include <stdlib.h>
+ #include <string.h>
+ #include <math.h>
+ #include <process.h>
+#endif
+
+#define LASTCHAR 127 /* max dvi character, above are commands */
+
+#define get1() num(1)
+#define get2() num(2)
+#define get3() num(3)
+#define get4() num(4)
+#define sget1() snum(1)
+#define sget2() snum(2)
+#define sget3() snum(3)
+#define sget4() snum(4)
+
+typedef struct{
+ char *name;
+ char *mag;
+ int base;
+ int mode;
+} FONTDEF;
+
+typedef struct{
+ char *pattern;
+ int base;
+ int mode;
+} FONTPAT;
+
+#define MaxBAidx 10 /* maximum number of bases (plain, cm, etc.) */
+#define MaxMOidx 10 /* maximum number of modes (lj, fx, etc.) */
+
+int FDsize, FDidx; FONTDEF **Fontdefs;
+int FPsize, FPidx; FONTPAT **FPatterns;
+int BAidx; char *BAses[MaxBAidx];
+int MOidx; char *MOdes[MaxMOidx];
+int Nomfj;
+
+char *Inputmodes, *MFjobcmd, *Outname="dvimfj.mfj";
+
+FILE * dvifp;
+char * dvi_name;
+long pc;
+
+long Numerator, Denominator, Magnification;
+double Scale = 1;
+
+char * realloc ();
+
+void main ();
+void read_dvi_file ();
+void bop ();
+void preamble ();
+void postamble ();
+void postpostamble ();
+void fontdef ();
+void special ();
+unsigned long num ();
+long snum ();
+void addfontdef ();
+void * Realloc ();
+char * Strdup ();
+void read_config_file ();
+void read_config_80 ();
+void addpatterndef ();
+void write_mfj ();
+void run_mfjob ();
+
+
+
+
+/*---------------------------------------------------------------------------*/
+
+void main(argc, argv)
+int argc;
+char **argv;
+{
+ register int i, jx;
+ long scale;
+
+ if (argc < 2) {
+ usage:
+ printf("\nUsage: %s dvifile [magstep] [no]\n", *argv);
+ printf("\tFonts scaled (1.2^magstep) or (magstep/1000).\n"
+ "\tNo MFjob spawn.\n");
+ exit(1);
+ }
+
+ else{
+ if ((i = strlen(argv[1])) == 0) {
+ printf("Illegal empty filename\n");
+ exit(2);
+ }
+ if ((i >= 5) && !strcmpi(argv[1]+i-4, ".dvi")) dvi_name = argv[1];
+ else {
+ dvi_name = Realloc(0, (i+5) * sizeof(char));
+ strcpy(dvi_name, argv[1]);
+ strcat(dvi_name, ".dvi");
+ }
+ if ((dvifp = fopen(dvi_name, "rb")) == NULL) {
+ printf("Cant open %s\n", dvi_name);
+ exit(3);
+ }
+ if (argc > 2){
+ for (jx = 2; jx < argc; jx++){
+ if ('N' == toupper(argv[jx][0])){
+ Nomfj = 1;
+ continue;
+ }
+ scale = 0;
+ if (1 > sscanf(argv[jx], " %ld", &scale)) goto usage;
+ if (scale > 30) Scale = scale/1000.f;
+ else Scale = pow((double)1.2, (double)scale);
+ }
+ }
+ }
+
+ read_config_file(argv[0]);
+ read_dvi_file();
+ write_mfj();
+ run_mfjob();
+ exit(0);
+
+} /* main */
+
+
+void read_dvi_file()
+{
+ int opcode;
+
+ while ((opcode = (int) get1()) != EOF) { /* process until end of file */
+ if ((opcode <= LASTCHAR) && isprint(opcode)) {
+ while ((opcode <= LASTCHAR) && isprint(opcode)) {
+ opcode = (int) get1();
+ }
+ }
+
+ if (opcode <= LASTCHAR) ;
+ else if ((opcode >= FONT_00) && (opcode <= FONT_63)) ;
+ else switch (opcode) {
+ case SET1 :
+ case SET2 :
+ case SET3 :
+ case SET4 : num(opcode - SET1 + 1); break;
+ case SET_RULE : sget4(); sget4(); break;
+ case PUT1 :
+ case PUT2 :
+ case PUT3 :
+ case PUT4 : num(opcode - PUT1 + 1); break;
+ case PUT_RULE : sget4(); sget4();
+ case NOP : break;
+ case BOP : bop(); break;
+ case EOP :
+ case PUSH :
+ case POP : break;
+ case RIGHT1 :
+ case RIGHT2 :
+ case RIGHT3 :
+ case RIGHT4 : snum(opcode - RIGHT1 + 1);
+ case W0 : break;
+ case W1 :
+ case W2 :
+ case W3 :
+ case W4 : snum(opcode - W0);
+ case X0 : break;
+ case X1 :
+ case X2 :
+ case X3 :
+ case X4 : snum(opcode - X0); break;
+ case DOWN1 :
+ case DOWN2 :
+ case DOWN3 :
+ case DOWN4 : snum(opcode - DOWN1 + 1);
+ case Y0 : break;
+ case Y1 :
+ case Y2 :
+ case Y3 :
+ case Y4 : snum(opcode - Y0);
+ case Z0 : break;
+ case Z1 :
+ case Z2 :
+ case Z3 :
+ case Z4 : snum(opcode - Z0); break;
+ case FNT1 :
+ case FNT2 :
+ case FNT3 :
+ case FNT4 : num(opcode - FNT1 + 1); break;
+ case XXX1 :
+ case XXX2 :
+ case XXX3 :
+ case XXX4 : special(opcode - XXX1 + 1); break;
+ case FNT_DEF1 :
+ case FNT_DEF2 :
+ case FNT_DEF3 :
+ case FNT_DEF4 : fontdef(opcode - FNT_DEF1 + 1); break;
+ case PRE : preamble(); break;
+ case POST : postamble(); break;
+ case POST_POST: postpostamble(); break;
+ }
+ }
+
+} /* read_dvi_file */
+
+
+/*----------------------------------------------------------------------------*/
+
+
+void bop()
+{
+ int i;
+
+ for (i=0; i < 11; i++) get4();
+
+} /* bop */
+
+
+/*---------------------------------------------------------------------------*/
+
+void postamble()
+{
+ sget4();
+ if (Numerator != get4() ||
+ Denominator != get4() ||
+ Magnification != get4()){
+
+ printf("Postamble does not match preamble\n");
+ exit(3);
+ }
+ get4();
+ get4();
+ get2();
+ get2();
+
+} /* postamble */
+
+void preamble()
+{
+ long ix;
+
+ get1();
+ Numerator = get4();
+ Denominator = get4();
+ Magnification = get4();
+ ix = (long)(Scale*1000); /* truncate at third decimal place */
+ Scale = ((double)ix)/1000;
+ printf("\nmagnification: %ld scale: %05.3f\n\n", Magnification, Scale);
+ get1();
+
+} /* preamble */
+
+
+void postpostamble()
+{
+ register int i;
+
+ get4();
+ get1();
+ while ((i = (int) get1()) == TRAILER) ;
+ while (i != EOF) {
+ printf("%06ld: ", pc - 1);
+ printf("BAD DVI FILE END: 0x%02X\n", i);
+ i = (int) get1();
+ }
+
+} /* postpostamble */
+
+
+
+void special(x)
+register int x;
+{
+ register long len;
+ register long i;
+
+ len = num(x);
+ for (i = 0; i < len; i++) get1();
+
+} /* special */
+
+
+
+void fontdef(x)
+register int x;
+{
+ register int ix, jx;
+ long scale, design;
+ double mag;
+ char fontname[10], fontmag[10];
+
+ num(x);
+ get4();
+ scale = get4();
+ design = get4();
+ if (0==design) mag = -1;
+ else{
+ mag = (double)scale/(double)design;
+ mag = Scale*Magnification*mag/1000;
+ }
+ sprintf(fontmag, "%07.3f", mag);
+ ix = (int) get1() + (int) get1();
+
+#if defined(MSDOS)
+ #define LIMIT8 && jx < 8
+#else
+ #define LIMIT8
+#endif
+
+ for (jx=0; jx < ix LIMIT8; jx++) fontname[jx] = (char) get1();
+ fontname[jx] = 0;
+ for (; jx < ix; jx++) get1();
+ addfontdef(fontname, fontmag);
+
+} /* fontdef */
+
+
+
+unsigned long num(size)
+register int size;
+{
+ register int i;
+ register long x = 0;
+
+ pc += size;
+ for (i = 0; i < size; i++)
+ x = (x << 8) + (unsigned) getc(dvifp);
+ return x;
+
+} /* num */
+
+
+
+long snum(size)
+register int size;
+{
+ register int i;
+ register long x = 0;
+
+ pc += size;
+ x = getc(dvifp);
+ if (x & 0x80)
+ x -= 0x100;
+ for (i = 1; i < size; i++)
+ x = (x << 8) + (unsigned) getc(dvifp);
+ return x;
+
+} /* snum */
+
+void addfontdef(name, mag)
+char *name, *mag;
+{
+ int ix, jx, found, base, mode;
+ char *pat;
+
+ if (FDsize < 2+FDidx){
+ FDsize = 30+FDidx;
+ Fontdefs = Realloc(Fontdefs, FDsize * sizeof Fontdefs[0]);
+ }
+ for (ix=0; ix < FDidx; ix++){
+ if (!strcmp(Fontdefs[ix]->name, name) &&
+ !strcmp(Fontdefs[ix]->mag, mag)){
+ return;
+ }
+ }
+ for (found=ix=0; ix < FPidx; ix++){
+ pat = FPatterns[ix]->pattern;
+ for (jx=0; pat[jx] && pat[jx]==name[jx]; jx++);
+ if (pat[jx]=='*' || !strcmp(pat, name)){
+ base = FPatterns[ix]->base;
+ mode = FPatterns[ix]->mode;
+ found = 1;
+ break;
+ }
+ }
+ if (!found){
+ printf("Font %s not found in .CFG file\n", name);
+ exit(3);
+ }
+ Fontdefs[FDidx] = Realloc(NULL, sizeof(FONTDEF));
+ Fontdefs[FDidx]->name = Strdup(name);
+ Fontdefs[FDidx]->mag = Strdup(mag);
+ Fontdefs[FDidx]->base = base;
+ Fontdefs[FDidx]->mode = mode;
+ FDidx++;
+ printf("font: %-8s mag: %s base: %-8s mode: %s\n",
+ name, mag, BAses[base], MOdes[mode]);
+
+} /* addfontdef */
+
+void *Realloc(ptr, size)
+void *ptr;
+int size;
+{
+ void *outpntr;
+
+ if (size < 0) exit(11);
+ outpntr = realloc(ptr, size);
+ if (0==outpntr){
+ printf("Memory error\n");
+ exit(4);
+ }
+ return outpntr;
+
+} /* Realloc */
+
+char *Strdup(str)
+char *str;
+{
+ char *newstr;
+
+ newstr = strdup(str);
+ if (0==newstr){
+ printf("Strdup error\n");
+ exit(4);
+ }
+ return newstr;
+
+} /* Strdup */
+
+
+char Buf80[81];
+FILE *Cfp;
+
+void read_config_file(name)
+char *name;
+{
+int ix, sl;
+
+ sl = strlen(name); if (sl >= (80-5)) exit(10); strcpy(Buf80, name);
+ for (ix = sl-1; ix > 0 && ix > sl-5; ix--){
+ if (Buf80[ix]=='.'){
+ strcpy(Buf80+ix+1, "CFG");
+ Cfp = fopen(Buf80, "r"); if (0==Cfp){
+ printf("Can't open %s\n", Buf80);
+ exit(3);
+ }
+ read_config_80(); MFjobcmd = Strdup(Buf80);
+ read_config_80(); Inputmodes = Strdup(Buf80);
+ for (;;){
+ read_config_80();
+
+ if (!strcmp(Buf80, "*end")){
+ fclose(Cfp);
+ return;
+ }
+ if (!strcmp(Buf80, "*base")){
+ read_config_80();
+ BAses[BAidx++] = Strdup(Buf80);
+ if (BAidx >= MaxBAidx){
+ printf("Too many bases\n");
+ exit(3);
+ }
+ continue;
+ }
+ if (!strcmp(Buf80, "*mode")){
+ read_config_80();
+ MOdes[MOidx++] = Strdup(Buf80);
+ if (MOidx >= MaxMOidx){
+ printf("Too many modes\n");
+ exit(3);
+ }
+ continue;
+ }
+ if (!BAidx){
+ printf("Missing *base command\n");
+ exit(3);
+ }
+ if (!MOidx){
+ printf("Missing *mode command\n");
+ exit(3);
+ }
+ addpatterndef(Buf80, BAidx-1, MOidx-1);
+ }
+ }
+ }
+ printf("Missing *end command\n");
+ exit(3);
+
+} /* read_config_file */
+
+void read_config_80()
+{
+ if (1==fscanf(Cfp, " %80s", Buf80)) return;
+ printf("Can't read config file\n");
+ exit(3);
+}
+
+void addpatterndef(pattern, base, mode)
+char *pattern;
+int base, mode;
+{
+ if (FPsize < 2+FPidx){
+ FPsize = 10+FPidx;
+ FPatterns = Realloc(FPatterns, FPsize * sizeof FPatterns[0]);
+ }
+ FPatterns[FPidx] = Realloc(NULL, sizeof(FONTDEF));
+ FPatterns[FPidx]->pattern = Strdup(pattern);
+ FPatterns[FPidx]->base = base;
+ FPatterns[FPidx]->mode = mode;
+ FPidx++;
+
+} /* addpatterndef */
+
+void write_mfj()
+{
+ int ix, jx, mx, nx, flag;
+ FILE *fp;
+
+ fp = fopen(Outname, "w");
+ if (0==fp){
+ printf("Can't create %s\n", Outname);
+ exit(3);
+ }
+ fprintf(fp, "%s\n", Inputmodes);
+ for (mx=0; mx < MOidx; mx++){
+ for (jx=0; jx < BAidx; jx++){
+ flag = 0;
+ for (ix=0; ix < FDidx; ix++){
+ if (mx != Fontdefs[ix]->mode) continue;
+ if (jx != Fontdefs[ix]->base) continue;
+ if (!flag){
+ fprintf(fp, "{\n base=%s;\n %s;\n",
+ BAses[jx], MOdes[mx]);
+ flag = 1;
+ }
+ nx = fprintf(fp, " { font=%s;", Fontdefs[ix]->name);
+ fprintf(fp, "%*smag=%s; }\n", 21-nx, " ", Fontdefs[ix]->mag);
+ }
+ if (flag) fprintf(fp, "}\n");
+ }
+ }
+ fclose(fp);
+
+} /* write_mfj */
+
+void run_mfjob()
+{
+ int retcode;
+
+ if (Nomfj) return;
+ printf("\nSpawning %s %s\n\n", MFjobcmd, Outname);
+ retcode = spawnl(P_WAIT, MFjobcmd, MFjobcmd, Outname, NULL);
+ if (0==retcode){
+ printf("\nDeleting %s\n", Outname);
+ unlink(Outname);
+ }
+
+} /* run_mfjob */
+
+
+
+/*
+
+
+================================================================================
+== DVI file format ==
+================================================================================
+no_ops >= 0 bytes (NOP, nops before the preamble)
+preamble_marker 1 ubyte (PRE)
+version_id 1 ubyte (should be version 2)
+numerator 4 ubytes (numerater must equal the one in postamble)
+denominator 4 ubytes (denominator must equal the one in postamble)
+magnification 4 ubytes (magnification must equal the one in postamble)
+id_len 1 ubyte (lenght of identification string)
+id_string id_len ubytes (identification string)
+
+no_ops >= 0 bytes (NOP, nops before a page)
+begin_of_page 1 ubyte (BOP)
+page_nr 4 sbytes (page number)
+do_be_do 36 bytes (filler ????)
+prev_page_offset 4 sbytes (offset in file where previous page starts, -1 for none)
+... PAGE DATA ...
+end_of_page 1 ubyte (EOP)
+
+no_ops ??? >= 0 bytes (NOPS, I think they are allowed here...)
+postamble_marker 1 ubyte (POST)
+last_page_offset 4 sbytes (offset in file where last page starts)
+numerator 4 ubytes (numerater must equal the one in preamble)
+denominator 4 ubytes (denominator must equal the one in preamble)
+magnification 4 ubytes (magnification must equal the one in preamble)
+max_page_height 4 ubytes (maximum page height)
+max_page_width 4 ubytes (maximum page width)
+max_stack 2 ubytes (maximum stack depth needed)
+total_pages 2 ubytes (number of pages in file)
+... FONT DEFINITIONS ...
+
+postamble_offset 4 sbytes (offset in file where postamble starts)
+version_id 1 ubyte (should be version 2)
+trailer >= 4 ubytes (TRAILER)
+<EOF>
+
+
+FONT DEFINITIONS:
+ do {
+ switch (c = getc(dvi_fp) {
+ case FNTDEF1 :
+ case FNTDEF2 :
+ case FNTDEF3 :
+ case FNTDEF4 : define_font(c);
+ case POSTPOST : break;
+ default : error;
+ }
+ } while (c != POSTPOST);
+
+===== A font def looks like:
+
+1,2,3 or 4 ubytes TeXfontnumber for FNTDEF1 .. FNTDEF4
+4 ubytes checksum
+4 ubytes scale
+4 ubytes design size
+1 byte deflen1
+1 byte deflen2
+deflen1 + deflen2 bytes fontname.
+
+===== A special looks like:
+
+1,2,3 or 4 ubytes telling length of special command for XXX1 .. XXX4
+all bytes in the special command are used as defined in the dvi driver.
+
+
+*/