diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/quicspool/src |
Initial commit
Diffstat (limited to 'dviware/quicspool/src')
42 files changed, 9897 insertions, 0 deletions
diff --git a/dviware/quicspool/src/cat.c b/dviware/quicspool/src/cat.c new file mode 100644 index 0000000000..bd3e52b8aa --- /dev/null +++ b/dviware/quicspool/src/cat.c @@ -0,0 +1,560 @@ +#ifndef lint +static char *rcs = "$Header: cat.c,v 1.1 88/01/15 13:03:09 simpson Rel $"; +#endif +/* +$Log: cat.c,v $ + * Revision 1.1 88/01/15 13:03:09 simpson + * initial release + * + * Revision 0.1 87/12/11 18:30:40 simpson + * beta test + * +*/ + +/* This file contains structure for mapping between ASCII and the weird + * CAT otroff font positions. The CAT only contains 102 characters per + * font mapped into strange positions. + */ + +/* This table maps from CAT otroff order of a non-special font to the position + * of the character in the real font. + */ +char RegularToAscii[128] = { +0, /* Not used */ +'h', /* h */ +'t', /* t */ +'n', /* n */ +'m', /* m */ +'l', /* l */ +'i', /* i */ +'z', /* z */ +'s', /* s */ +'d', /* d */ +'b', /* b */ +'x', /* x */ +'f', /* f */ +'j', /* j */ +'u', /* u */ +'k', /* k */ +0, /* Not used */ +'p', /* p */ +006, /* \(em */ +';', /* ; */ +0, /* Not used */ +'a', /* a */ +005, /* \(ru */ +'c', /* c */ +'`', /* ` */ +'e', /* e */ +'\'', /* ' */ +'o', /* o */ +021, /* \(14 */ +'r', /* r */ +022, /* \(12 */ +'v', /* v */ +'-', /* - or \(hy */ +'w', /* w */ +'q', /* q */ +'/', /* / */ +'.', /* . */ +'g', /* g */ +023, /* \(34 */ +',', /* , */ +'&', /* & */ +'y', /* y */ +0, /* Not used */ +'%', /* % */ +0, /* Not used */ +'Q', /* Q */ +'T', /* T */ +'O', /* O */ +'H', /* H */ +'N', /* N */ +'M', /* M */ +'L', /* L */ +'R', /* R */ +'G', /* G */ +'I', /* I */ +'P', /* P */ +'C', /* C */ +'V', /* V */ +'E', /* E */ +'Z', /* Z */ +'D', /* D */ +'B', /* B */ +'S', /* S */ +'Y', /* Y */ +0, /* Not used */ +'F', /* F */ +'X', /* X */ +'A', /* A */ +'W', /* W */ +'J', /* J */ +'U', /* U */ +'K', /* K */ +'0', /* 0 */ +'1', /* 1 */ +'2', /* 2 */ +'3', /* 3 */ +'4', /* 4 */ +'5', /* 5 */ +'6', /* 6 */ +'7', /* 7 */ +'8', /* 8 */ +'9', /* 9 */ +'*', /* * */ +004, /* \- or \(-- */ +001, /* \(fi */ +002, /* \(fl */ +003, /* \(ff */ +020, /* \(ct */ +012, /* \(fL or \(Fl */ +011, /* \fI or \(Fi */ +'(', /* ( */ +')', /* ) */ +'[', /* [ */ +']', /* ] */ +013, /* \(de */ +014, /* \(dg */ +'=', /* = */ +017, /* \(rg */ +':', /* : */ +'+', /* + */ +0, /* Not used */ +'!', /* ! */ +007, /* \(bu */ +'?', /* ? */ +015, /* \(fm */ +'|', /* | */ +0, /* Not used */ +016, /* \(co */ +010, /* \(sq */ +'$', /* $ */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +}; + +/* This table maps from CAT otroff order in a special font to the position + * of the character in the real font. + */ +char SpecialToAscii[128] = { +0, /* Not used */ +'w', /* \(*q */ +'h', /* \(*h */ +'m', /* \(*n */ +'l', /* \(*m */ +'k', /* \(*l */ +'i', /* \(*i */ +'f', /* \(*z */ +'r', /* \(*s */ +'d', /* \(*d */ +'b', /* \(*b */ +'n', /* \(*c */ +'g', /* \(*y */ +'u', /* \(*f */ +'t', /* \(*u */ +'j', /* \(*k */ +0, /* Not used */ +'p', /* \(*p */ +'@', /* @ */ +'7', /* \(da */ +0, /* Not used */ +'a', /* \(*a */ +'|', /* \(or */ +'v', /* \(*x */ +'"', /* " */ +'e', /* \(*e */ +'=', /* = */ +'o', /* \(*o */ +'4', /* \(<- */ +'q', /* \(*r */ +'6', /* \(ua */ +'s', /* \(*t */ +'_', /* _ */ +'\\', /* \e */ +'W', /* \(*Q */ +007, /* \(bs */ +001, /* \(if */ +'c', /* \(*g */ +002, /* \(fl */ +003, /* \(pt */ +004, /* \(rh */ +'x', /* \(*w */ +0, /* Not used */ +'(', /* \(gr */ +0, /* Not used */ +'U', /* \(*F */ +'H', /* \(*H */ +'X', /* \(*W */ +005, /* \(cu */ +006, /* \(rn */ +014, /* \(ts */ +'K', /* \(*L */ +'-', /* \(mi */ +'C', /* \(*G */ +015, /* \(is */ +'P', /* \(*P */ +032, /* \(sb */ +033, /* \(sp */ +'2', /* \(ap */ +'y', /* \(pd */ +'D', /* \(*D */ +013, /* \(sr */ +'R', /* \(*S */ +'1', /* \(~= */ +0, /* Not used */ +'>', /* > */ +'N', /* \(*C */ +'<', /* < */ +016, /* \(sl */ +034, /* \(ca */ +'T', /* \(*U */ +035, /* \(no */ +023, /* \(rc */ +024, /* \(lt */ +017, /* \(bv */ +030, /* \(lk */ +025, /* \(lb */ +026, /* \(rt */ +031, /* \(rk */ +027, /* \(rb */ +021, /* \(rf */ +020, /* \(lf */ +022, /* \(lc */ +'*', /* \(mu */ +'/', /* \(di */ +010, /* \(+- */ +011, /* \(<= */ +012, /* \(>= */ +'0', /* \(== */ +'3', /* \(!= */ +'{', /* { */ +'}', /* } */ +'\'', /* ' */ +'`', /* \` */ +'^', /* ^ */ +'#', /* # */ +036, /* \(lh */ +037, /* \(mo */ +'~', /* ~ */ +'z', /* \(es */ +0, /* Not used */ +'Y', /* \(dd */ +'Z', /* \(br */ +'9', /* \(** */ +'[', /* \(ib */ +']', /* \(ci */ +0, /* Not used */ +'+', /* \(pl */ +'5', /* \(-> */ +'8', /* \(sc */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0, /* Not used */ +0 /* Not used */ +}; + +/* This tables maps from the order in the otroff width output table to + * the font position of that character. A zero value designates not used. + */ +char RegularOrder[256-32] = { +' ', +'!', +0, /* " */ +0, /* # */ +'$', +'%', +'&', +'\'', +'(', +')', +'*', +'+', +',', +'-', /* hyphen */ +'.', +'/', +'0', +'1', +'2', +'3', +'4', +'5', +'6', +'7', +'8', +'9', +':', +';', +0, /* < */ +'=', +0, /* > */ +'?', +0, /* @ */ +'A', +'B', +'C', +'D', +'E', +'F', +'G', +'H', +'I', +'J', +'K', +'L', +'M', +'N', +'O', +'P', +'Q', +'R', +'S', +'T', +'U', +'V', +'W', +'X', +'Y', +'Z', +'[', +0, /* \ */ +']', +0, /* ^ */ +0, /* _ */ +'`', +'a', +'b', +'c', +'d', +'e', +'f', +'g', +'h', +'i', +'j', +'k', +'l', +'m', +'n', +'o', +'p', +'q', +'r', +'s', +'t', +'u', +'v', +'w', +'x', +'y', +'z', +0, /* { */ +'|', +0, /* } */ +0, /* ~ */ +0, /* narrow space */ +055, /* hyphen */ +007, /* bullet */ +010, /* square */ +006, /* 3/4 em */ +005, /* rule */ +021, /* 1/4 */ +022, /* 1/2 */ +023, /* 3/4 */ +004, /* minus */ +001, /* fi */ +002, /* fl */ +003, /* ff */ +011, /* ffi */ +012, /* ffl */ +013, /* degree */ +014, /* dagger */ +0, /* section */ +015, /* foot mark */ +0, /* ' */ +0, /* ` */ +0, /* _ */ +0, +0, /* half narrow space */ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +017, /* registered */ +016, /* copyright */ +0, +020 /* cent */ +}; + +/* Just like RegularOrder, but for the special font */ +char SpecialOrder[256-32] = { +0,0, +'"', +'#', +0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0, +'<', +0, +'>', +0, +'@', +0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0, +'\\', +0, +'^', +'_', +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0, +'{', +0, +'}', +'~', +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +070, /* section */ +0, +'\'', +'`', +'_', +016, /* slash (longer) */ +0, +0, +0141, /* alpha */ +0142, /* beta */ +0143, /* gamma */ +0144, /* delta */ +0145, /* epsilon */ +0146, /* zeta */ +0147, /* eta */ +0150, /* theta */ +0151, /* iota */ +0152, /* kappa */ +0153, /* lambda */ +0154, /* mu */ +0155, /* nu */ +0156, /* xi */ +0157, /* omicron */ +0160, /* pi */ +0161, /* rho */ +0162, /* sigma */ +0163, /* tau */ +0164, /* upsilon */ +0165, /* phi */ +0166, /* chi */ +0167, /* psi */ +0170, /* omega */ +0103, /* Gamma */ +0104, /* Delta */ +0110, /* Theta */ +0113, /* Lambda */ +0116, /* Xi */ +0120, /* Pi */ +0122, /* Sigma */ +0, +0124, /* Upsilon */ +0125, /* Phi */ +0127, /* Psi */ +0130, /* Omega */ +013, /* square root */ +014, /* terminal sigma */ +006, /* root extender */ +012, /* >= */ +011, /* <= */ +060, /* identically equal */ +055, /* minus */ +061, /* approximately = */ +062, /* approximates */ +063, /* not equal */ +065, /* right arrow */ +064, /* left arrow */ +066, /* up arrow */ +067, /* down arrow */ +'=', +052, /* multiply */ +057, /* divide */ +010, /* plus minus */ +005, /* cup (union) */ +034, /* cap (intersection) */ +032, /* subset of */ +033, /* superset of */ +0133, /* improper subset */ +002, /* improper superset */ +001, /* infinity */ +0171, /* partial derivative */ +050, /* gradient */ +035, /* not */ +015, /* integral sign */ +003, /* proportional to */ +0172, /* empty set */ +037, /* member of */ +'+', +0, +0, +0, /* box vertical rule */ +0, +0131, /* double dagger */ +004, /* right hand */ +036, /* left hand */ +071, /* math * */ +007, /* bell system sign */ +'|', /* or */ +0135, /* circle */ +024, /* left top (of big curly) */ +025, /* left bottom */ +026, /* right top */ +027, /* right bottom */ +022, /* left center of big curly bracket */ +023, /* right center of big curly bracket */ +017, /* bold vertical */ +020, /* left floor */ +021, /* right floor */ +022, /* left ceiling */ +023 /* right ceiling */ +}; + + diff --git a/dviware/quicspool/src/cati.c b/dviware/quicspool/src/cati.c new file mode 100644 index 0000000000..e34ad05ad3 --- /dev/null +++ b/dviware/quicspool/src/cati.c @@ -0,0 +1,709 @@ +#ifndef lint +static char *rcs = "$Header: cati.c,v 1.1 88/01/15 13:03:12 simpson Rel $"; +#endif +/* +$Log: cati.c,v $ + * Revision 1.1 88/01/15 13:03:12 simpson + * initial release + * + * Revision 0.1 87/12/11 18:30:41 simpson + * beta test + * +*/ +#include <stdio.h> +/* mask for high order 4 bits of byte */ +#define CAT_HIGH_NIBBLE 0xf0 +#define CAT_MAX_BYTE 0xff + +#define CAT_ESCAPE_CODE 0x80 +#define CAT_ESCAPE_MASK 0x7f +#define CAT_MAX_ESCAPE 0x7f +/* nonzero if escape command and zero otherwise */ +#define CAT_IS_ESCAPE(x) (((x) & (CAT_HIGH_NIBBLE << 3)) == CAT_ESCAPE_CODE) +/* magnitude of escape */ +#define CAT_ESCAPE(x) (~(x) & CAT_ESCAPE_MASK) +#define CAT_ENCODE_ESCAPE(n) (CAT_ESCAPE_CODE | (~(n) & CAT_ESCAPE_MASK)) + +#define CAT_LEAD_CODE 0x60 +#define CAT_LEAD_MASK 0x1f +#define CAT_MAX_LEAD 0x1f +/* nonzero if leading command and zero otherwise */ +#define CAT_IS_LEADING(x) (((x) & (CAT_HIGH_NIBBLE << 1)) == CAT_LEAD_CODE) +/* magnitude of leading */ +#define CAT_LEAD(x) (~(x) & CAT_MAX_LEAD) +#define CAT_ENCODE_LEAD(n) (CAT_LEAD_CODE | (~(n) & CAT_LEAD_MASK)) + +#define CAT_SIZE_CHANGE_CODE 0x50 +/* nonzero if point size change command and zero otherwise */ +#define CAT_IS_SIZE_CHANGE(x) (((x) & CAT_HIGH_NIBBLE) == CAT_SIZE_CHANGE_CODE) + +/* translates from the weird CAT point size change codes into something sane */ +#define CAT_SIZE_CHANGE(x) \ + ((x) == 0x50 ? 7 : \ + (x) == 0x51 ? 8 : \ + (x) == 0x52 ? 10 : \ + (x) == 0x53 ? 11 : \ + (x) == 0x54 ? 12 : \ + (x) == 0x55 ? 14 : \ + (x) == 0x56 ? 18 : \ + (x) == 0x57 ? 9 : \ + (x) == 0x58 ? 6 : \ + (x) == 0x59 ? 16 : \ + (x) == 0x5a ? 20 : \ + (x) == 0x5b ? 22 : \ + (x) == 0x5c ? 24 : \ + (x) == 0x5d ? 28 : \ + (x) == 0x5e ? 36 : 0) + +/* translates from sane point sizes into the weird CAT encodings */ +#define CAT_ENCODE_SIZE(x) \ + ((x) == 6 ? 0x58 : \ + (x) == 7 ? 0x50 : \ + (x) == 8 ? 0x51 : \ + (x) == 9 ? 0x57 : \ + (x) == 10 ? 0x52 : \ + (x) == 11 ? 0x53 : \ + (x) == 12 ? 0x54 : \ + (x) == 14 ? 0x55 : \ + (x) == 16 ? 0x59 : \ + (x) == 18 ? 0x56 : \ + (x) == 20 ? 0x5a : \ + (x) == 22 ? 0x5b : \ + (x) == 24 ? 0x5c : \ + (x) == 28 ? 0x5d : \ + (x) == 36 ? 0x5e : 0) + +#define CAT_FLASH_CODE 0x00 +#define CAT_FLASH_MASK 0x3f +#define CAT_MAX_FLASH 0x3f +/* nonzero if printable character and zero otherwise */ +#define CAT_IS_FLASH(x) (((x) & (CAT_HIGH_NIBBLE << 2)) == CAT_FLASH_CODE) +#define CAT_FLASH(x) ((x) & CAT_MAX_FLASH) +#define CAT_ENCODE_FLASH(n) (CAT_FLASH_CODE | ((n) & CAT_FLASH_MASK)) + +#define CAT_CONTROL_CODE 0x40 +/* nonzero if control command and zero otherwise */ +#define CAT_IS_CONTROL(x) (((x) & CAT_HIGH_NIBBLE) == CAT_CONTROL_CODE) + +/* CAT-8 control commands */ +#define CAT_INITIALIZE 0x40 +#define CAT_LOWER_RAIL 0x41 +#define CAT_UPPER_RAIL 0x42 +#define CAT_UPPER_MAGAZINE 0x43 +#define CAT_LOWER_MAGAZINE 0x44 +#define CAT_LOWER_FONT 0x45 +#define CAT_UPPER_FONT 0x46 +#define CAT_ESCAPE_FORWARD 0x47 +#define CAT_ESCAPE_BACKWARD 0x48 +#define CAT_STOP 0x49 +#define CAT_LEAD_FORWARD 0x4a +#define CAT_LEAD_BACKWARD 0x4c +#define CAT_TILT_UP 0x4e +#define CAT_TILT_DOWN 0x4f +#define CAT_NOOP 0x00 +/* trapdoor for CAT extensions */ +#define CAT_EXTENSION 0x4b + +/* CAT_BIG_LEAD means take the next byte * 64 to obtain leading */ +#define CAT_BIG_LEAD 0x01 +#define CAT_BIG_LEAD_MULTIPLIER 64 +#define CAT_MIN_BIG_LEAD (CAT_BIG_LEAD_MULTIPLIER * 0x01) +#define CAT_MAX_BIG_LEAD (CAT_BIG_LEAD_MULTIPLIER * 0xff) + +/* CAT_BIG_ESCAPE means take the next byte * 128 to obtain escape */ +#define CAT_BIG_ESCAPE 0x02 +#define CAT_BIG_ESCAPE_MULTIPLIER 128 +#define CAT_MIN_BIG_ESCAPE (CAT_BIG_ESCAPE_MULTIPLIER * 0x01) +#define CAT_MAX_BIG_ESCAPE (CAT_BIG_ESCAPE_MULTIPLIER * 0xff) + +/* + * CAT_FORMFEED means advance to next page resetting current row + * and column to <0,0>. + */ +#define CAT_FORMFEED 0x03 + +/* + * Returns nonzero if a single point size and zero otherwise. + * The parameter is the `sane' point size and NOT the weird CAT encoding. + */ +#define CAT_IS_SINGLE(p) ((6 <= (p) && (p) <= 14) || (p) == 18) + +/* + * Returns nonzero is a double point size and zero otherwise. + * The parmeter is the `sane' point size and NOT the weird CAT encoding. + */ +#define CAT_IS_DOUBLE(p) ((p) == 16 || (p) >= 20) + +/* + * Returns nonzero if the old to new point size transition is a + * single to double transition and zero otherwise. + * The parameters are the `sane' point sizes NOT the weird CAT encodings. + */ +#define CAT_IS_SINGLE_TO_DOUBLE(old, new) \ + (CAT_IS_SINGLE(old) && CAT_IS_DOUBLE(new)) + +/* + * Returns nonzero if the old to new point size transition is a + * double to single transition and zero otherwise. + * The parameters are the `sane' point sizes NOT the weird CAT encodings. + */ +#define CAT_IS_DOUBLE_TO_SINGLE(old, new) \ + (CAT_IS_DOUBLE(old) && CAT_IS_SINGLE(new)) + +typedef struct CAT { + char escape_where; /* BACKWARD or FORWARD */ + char lead_where; /* BACKWARD or FORWARD */ + char font; /* bit 0 => tilt, bit 1 => rail, bit 2 => magazine */ + char font_half; /* LOWER or UPPER */ + char point_size; /* current point size */ +} CAT; + +#define CAT_FORWARD 0 +#define CAT_BACKWARD 1 +#define CAT_UPPER 0 +#define CAT_LOWER 1 + +/* vertical resolution per inch */ +#define CAT_VERTICAL_UNITS 144.0 +/* horizontal resolution per inch */ +#define CAT_HORIZONTAL_UNITS 432.0 + +/* compensatory escape for single/double point size transitions */ +#define CAT_LENSE_COMPENSATION 55 + +#define CAT_TILT 01 +#define CAT_RAIL 02 +#define CAT_MAGAZINE 04 + +/* default troff and scribe font mountings for CAT-8 */ +#define CAT_ROMAN_FONT 0 +#define CAT_ITALIC_FONT 2 +#define CAT_BOLD_FONT 4 +#define CAT_SPECIAL_FONT 6 + +/* the maximum number of characters on a filmstrip */ +#define CAT_MAX_FONT_INDEX 108 + + +FILE *freopen(); + +typedef struct STATE { + CAT cat; + long escape; /* temporary escape accumulator */ + long forward_escape; /* total forward escape to date */ + long backward_escape; /* total backward escape to date */ + long lead; /* temporary lead accumulator */ + long forward_lead; /* total forward lead to date */ + long backward_lead; /* total backward lead to date */ + long row; /* current row */ + long column; /* current column */ +} STATE; + +char *regular[128]; +char *special[128]; +char *Whoami; + +main (argc, argv) +int argc; +char *argv[]; +{ + int lead_only_flag = 0; + int verbose_flag = 0; + STATE s; + int i; + + Whoami = argv[0]; + for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) + switch (argv[0][1]) { + case 'l': + lead_only_flag++; + continue; + + case 'v': + verbose_flag++; + continue; + + default: + fprintf(stderr, "%s: unknown option %s\n", Whoami, argv[0]); + exit(1); + } + + if (argc > 0) + if (freopen(argv[0], "r", stdin) == NULL) { + fprintf(stderr, "%s: cannot open %s\n", Whoami, argv[0]); + exit(1); + } + + s.escape = s.forward_escape = s.backward_escape = 0; + s.lead = s.forward_lead = s.backward_lead = 0; + s.row = s.column = 0; + while ((i = getchar()) != EOF) + interpret(i, &s, !lead_only_flag, verbose_flag); + printf("Total lead %d\n", s.forward_lead + s.backward_lead); + exit(0); +} + +interpret (c, s, noisy, verbose) +int c; +STATE *s; +int noisy; +int verbose; +{ + int point_size; + int index; /* temporary for computing filmstrip index */ + int lead; + int escape; + + if (c == 0) { + if (noisy) + printf("No-op\n"); + return; /* ascii null is a no-op for the CAT */ + } + + if (CAT_IS_ESCAPE(c)) { + s->escape += CAT_ESCAPE(c); + if (noisy & verbose) + printf("%c %d\n", s->cat.escape_where == CAT_FORWARD ? '>' : '<', CAT_ESCAPE(c)); + return; + } + + if (s->escape) { + if (s->cat.escape_where == CAT_FORWARD) { + s->forward_escape += s->escape; + s->column += s->escape; + if (noisy) + printf("> %d %d %d %d\n", + s->escape, + s->forward_escape, + s->backward_escape, + s->forward_escape + s->backward_escape); + } else { + s->backward_escape += s->escape; + s->column -= s->escape; + if (noisy) + printf("< %d %d %d %d\n", + s->escape, + s->forward_escape, + s->backward_escape, + s->forward_escape + s->backward_escape); + } + s->escape = 0; + } + + if (CAT_IS_LEADING(c)) { + s->lead += CAT_LEAD(c); + if (noisy & verbose) + printf("%c %d\n", s->cat.lead_where == CAT_FORWARD ? '+' : '-', CAT_LEAD(c)); + return; + } + + if (s->lead) { + if (s->cat.lead_where == CAT_FORWARD) { + s->forward_lead += s->lead; + s->row += s->lead; + if (noisy) + printf("+ %d %d %d %d\n", + s->lead, + s->forward_lead, + s->backward_lead, + s->forward_lead + s->backward_lead); + } else { + s->backward_lead += s->lead; + s->row -= s->lead; + if (noisy) + printf("- %d %d %d %d\n", + s->lead, + s->forward_lead, + s->backward_lead, + s->forward_lead + s->backward_lead); + } + s->lead = 0; + } + + if (CAT_IS_SIZE_CHANGE(c)) { + point_size = CAT_SIZE_CHANGE(c); + if (noisy) { + printf("Size %d", point_size); + if (CAT_IS_SINGLE_TO_DOUBLE(s->cat.point_size, point_size)) + printf(" (double)"); + else if (CAT_IS_DOUBLE_TO_SINGLE(s->cat.point_size, point_size)) + printf(" (single)"); + putchar('\n'); + } + s->cat.point_size = point_size; + return; + } + + if (CAT_IS_FLASH(c)) { + c = CAT_FLASH(c); + if (noisy) { + index = c + (s->cat.font_half == CAT_LOWER ? 0 : 63); + if (index > CAT_MAX_FONT_INDEX) { + printf("Flash !!ILLEGAL!! (%d)\n", index); + return; + } + printf("Flash %s (font %d %d%c size %d <%d,%d>)\n", + s->cat.font == CAT_SPECIAL_FONT ? special[index] : regular[index], + s->cat.font + 1, + c, + s->cat.font_half == CAT_LOWER ? 'L' : 'U', + s->cat.point_size, + s->row, + s->column); + } + return; + } + + switch (c) { + + case CAT_INITIALIZE: + s->cat.escape_where = s->cat.lead_where = CAT_FORWARD; + s->cat.font = 0; /* tilt up, lower rail and lower magazine */ + s->cat.font_half = CAT_LOWER; + s->column = 0; + if (noisy) + printf("Initialize\n"); + return; + + case CAT_LOWER_RAIL: + s->cat.font &= ~CAT_RAIL; + if (noisy) + printf("Lower rail (font %d)\n", s->cat.font + 1); + return; + + case CAT_UPPER_RAIL: + s->cat.font |= CAT_RAIL; + if (noisy) + printf("Upper rail (font %d)\n", s->cat.font + 1); + return; + + case CAT_UPPER_MAGAZINE: + s->cat.font |= CAT_MAGAZINE; + if (noisy) + printf("Upper magazine (font %d)\n", s->cat.font + 1); + return; + + case CAT_LOWER_MAGAZINE: + s->cat.font &= ~CAT_MAGAZINE; + if (noisy) + printf("Lower magazine (font %d)\n", s->cat.font + 1); + return; + + case CAT_LOWER_FONT: + s->cat.font_half = CAT_LOWER; + if (noisy) + printf("Font half lower\n"); + return; + + case CAT_UPPER_FONT: + s->cat.font_half = CAT_UPPER; + if (noisy) + printf("Font half upper\n"); + return; + + case CAT_ESCAPE_FORWARD: + s->cat.escape_where = CAT_FORWARD; + if (noisy) + printf("> mode, %d %d %d\n", + s->forward_escape, + s->backward_escape, + s->forward_escape + s->backward_escape); + return; + + case CAT_ESCAPE_BACKWARD: + s->cat.escape_where = CAT_BACKWARD; + if (noisy) + printf("< mode %d %d %d\n", + s->forward_escape, + s->backward_escape, + s->forward_escape + s->backward_escape); + return; + + case CAT_STOP: + if (noisy) + printf("STOP\n"); + return; + + case CAT_LEAD_FORWARD: + s->cat.lead_where = CAT_FORWARD; + if (noisy) + printf("+ mode %d %d %d\n", + s->forward_lead, + s->backward_lead, + s->forward_lead + s->backward_lead); + return; + + case CAT_LEAD_BACKWARD: + s->cat.lead_where = CAT_BACKWARD; + if (noisy) + printf("- mode %d %d %d\n", + s->forward_lead, + s->backward_lead, + s->forward_lead + s->backward_lead); + return; + + case CAT_EXTENSION: + switch (getchar()) { + case CAT_BIG_LEAD: + lead = getchar() * CAT_BIG_LEAD_MULTIPLIER; + if (noisy & verbose) + printf("%s %d\n", s->cat.lead_where == CAT_FORWARD ? "++" : "--", lead); + s->lead += lead; + return; + + case CAT_BIG_ESCAPE: + escape = getchar() * CAT_BIG_ESCAPE_MULTIPLIER; + if (noisy & verbose) + printf("%s %d\n", s->cat.escape_where == CAT_FORWARD ? ">>" : "<<", escape); + s->escape += escape; + return; + + case CAT_FORMFEED: + s->row = s->column = 0; + if (noisy) + printf("Formfeed\n"); + return; + + default: + if (noisy) + printf("Undefined extension\n"); + return; + } + + case CAT_TILT_UP: + s->cat.font &= ~CAT_TILT; + if (noisy) + printf("Tilt up (font %d)\n", s->cat.font + 1); + return; + + case CAT_TILT_DOWN: + s->cat.font |= CAT_TILT; + if (noisy) + printf("Tilt down (font %d)\n", s->cat.font + 1); + return; + } +} + +char *regular[128] = { + "", /* garbage slot */ + "h", /* h */ + "t", /* t */ + "n", /* n */ + "m", /* m */ + "l", /* l */ + "i", /* i */ + "z", /* z */ + "s", /* s */ + "d", /* d */ + "b", /* b */ + "x", /* x */ + "f", /* f */ + "j", /* j */ + "u", /* u */ + "k", /* k */ + "-blank-", /* blank */ + "p", /* p */ + "-", /* _ 3/4 em dash */ + ";", /* ; */ + "-blank-", /* blank */ + "a", /* a */ + "_", /* rule */ + "c", /* c */ + "`", /* ` open */ + "e", /* e */ + "'", /* ' close */ + "o", /* o */ + "-1/4-", /* 1/4 */ + "r", /* r */ + "-1/2-", /* 1/2 */ + "v", /* v */ + "-", /* - hyphen */ + "w", /* w */ + "q", /* q */ + "/", /* / */ + ".", /* . */ + "g", /* g */ + "-3/4-", /* 3/4 */ + ",", /* , */ + "&", /* & */ + "y", /* y */ + "-blank-", /* blank */ + "%", /* % */ + "-blank-", /* blank */ + "Q", /* Q */ + "T", /* T */ + "O", /* O */ + "H", /* H */ + "N", /* N */ + "M", /* M */ + "L", /* L */ + "R", /* R */ + "G", /* G */ + "I", /* I */ + "P", /* P */ + "C", /* C */ + "V", /* V */ + "E", /* E */ + "Z", /* Z */ + "D", /* D */ + "B", /* B */ + "S", /* S */ + "Y", /* Y */ + "F", /* F */ + "X", /* X */ + "A", /* A */ + "W", /* W */ + "J", /* J */ + "U", /* U */ + "K", /* K */ + "0", /* 0 */ + "1", /* 1 */ + "2", /* 2 */ + "3", /* 3 */ + "4", /* 4 */ + "5", /* 5 */ + "6", /* 6 */ + "7", /* 7 */ + "8", /* 8 */ + "9", /* 9 */ + "*", /* * */ + "-", /* minus */ + "-fi-", /* fi */ + "-fl-", /* fl */ + "-ff-", /* ff */ + "-cent mark-", /* cent mark */ + "-ffl-", /* ffl */ + "-ffi-", /* ffi */ + "(", /* ( */ + ")", /* ) */ + "[", /* [ */ + "]", /* ] */ + "-degree-", /* degree */ + "-dagger-", /* dagger */ + "=", /* = */ + "-registered-", /* registered */ + ":", /* : */ + "+", /* + */ + "-blank-", /* blank */ + "!", /* ! */ + "-bullet-", /* bullet */ + "?", /* ? */ + "'", /* foot mark */ + "|", /* | */ + "-blank-", /* blank */ + "-copyright-", /* copyright */ + "-square-", /* square */ + "$" /* $ */ +}; + +char *special[128] = { + "", /* garbage slot */ + "-psi-", /* psi */ + "-theta-", /* theta */ + "-nu-", /* nu */ + "-mu-", /* mu */ + "-lambda-", /* lambda */ + "-iota-", /* iota */ + "-zeta-", /* zeta */ + "-sigma-", /* sigma */ + "-delta-", /* delta */ + "-beta-", /* beta */ + "-xi-", /* xi */ + "-eta-", /* eta */ + "-phi", /* phi */ + "-upsilon-", /* upsilon */ + "-kappa-", /* kappa */ + "-blank-", /* blank */ + "-pi-", /* pi */ + "@", /* at sign @ */ + "-down arrow-", /* down arrow */ + "-blank-", /* blank */ + "-alpha-", /* alpha */ + "|", /* or */ + "-chi-", /* chi */ + "\"", /* " */ + "-epsilon-", /* epsilon */ + "=", /* equals */ + "-omicron-", /* omicron */ + "-left arrow-", /* left arrow */ + "-rho-", /* rho */ + "-up arrow-", /* up arrow */ + "-tau-", /* tau */ + "_", /* underrule */ + "\\", /* \ */ + "-Psi-", /* Psi */ + "-bell system sign-", /* bell system sign */ + "-infinity-", /* infinity */ + "-gamma-", /* gamma */ + "-improper subset-", /* improper superset */ + "-proportional to-", /* proportional to */ + "-right hand-", /* right hand */ + "-omega-", /* omega */ + "-blank-", /* blank */ + "-gradient-", /* gradient */ + "-blank-", /* blank */ + "-Phi-", /* Phi */ + "-Theta-", /* Theta */ + "-Omega-", /* Omega */ + "-union-", /* cup (union) */ + "-root en-", /* root en */ + "-terminal sigma-", /* terminal sigma */ + "-Lambda-", /* Lambda */ + "-", /* some horizontal line */ + "-Gamma-", /* Gamma */ + "-integral sign-", /* integral sign */ + "-Pi-", /* Pi */ + "-subset of-", /* subset of */ + "-superset of-", /* superset of */ + "-approximates-", /* approximates */ + "-partial derivative-", /* partial derivative */ + "-Delta-", /* Delta */ + "-square root-", /* square root */ + "-Sigma-", /* Sigma */ + "-approximates-", /* approximates */ + ">", /* > */ + "-Xi-", /* Xi */ + "<", /* < */ + "/", /* slash (longer) */ + "-cap-", /* cap (intersection) */ + "-Upsilon-", /* Upsilon */ + "-not-", /* not */ + "-right ceiling-", /* right ceiling */ + "-left curly top-", /* left top of big curly bracket */ + "-bold vertical-", /* bold vertical */ + "-left curly center-", /* left center of big curly bracket */ + "-left curly bottom-", /* left bottom of big curly bracket */ + "-right curly top-", /* right top of big curly bracket */ + "-right curly center-", /* right center of big curly bracket */ + "-right floor-", /* right floor */ + "-right floor-", /* right floor */ + "-left floor-", /* left floor */ + "-left ceiling-", /* left ceiling */ + "-multiply-", /* multiply */ + "-divide-", /* divide */ + "-plus/minus-", /* plus-minus */ + "-less than or equal-", /* <= */ + "-greater than or equal-", /* >= */ + "-identical-", /* identically equal */ + "-not equal-", /* not equal */ + "{", /* { */ + "}", /* } */ + "'", /* ' acute accent */ + "`", /* ` grave accent */ + "^", /* ^ */ + "#", /* sharp */ + "-left hand-", /* left hand */ + "-member of-", /* member of */ + "~", /* ~ */ + "-empty set-", /* empty set */ + "-blank-", /* blank */ + "-double dagger-", /* double dagger */ + "-box vertical rule-", /* box rule */ + "*", /* telephone asterisk? */ + "-improper subset-", /* improper subset */ + "-circle-", /* circle */ + "-blank-", /* blank */ + "+", /* equation plus sign */ + "-right arrow-", /* right arrow */ + "-section mark-" /* section mark */ +}; diff --git a/dviware/quicspool/src/cleanup.c b/dviware/quicspool/src/cleanup.c new file mode 100644 index 0000000000..571d902e27 --- /dev/null +++ b/dviware/quicspool/src/cleanup.c @@ -0,0 +1,86 @@ +#ifndef lint +static char *rcs = "$Header: cleanup.c,v 1.1 88/01/15 13:03:17 simpson Rel $"; +#endif +/* +$Log: cleanup.c,v $ + * Revision 1.1 88/01/15 13:03:17 simpson + * initial release + * + * Revision 0.1 87/12/11 18:30:43 simpson + * beta test + * +*/ + +/* Cleanup and error routines */ + +#include <stdio.h> +#include <local/profile.h> +#include <local/qms.h> +#include "constants.h" +#include "fontnode.h" + + +Boolean Accounting = FALSE; +FILE *Accting; +int NumPages = 0; +char *User; +char *Host; + +/* This routine is called on exit. It does some housekeeping before + * exiting. + */ +void cleanup(head, exitstatus) +struct FontNode *head; +int exitstatus; +{ + struct FontNode *p; + void sanestate(); + int portfont = 1204; + PROFILE_VALUE *v, *getbindingvalue(); + + for (p = head; p; p = p->next) /* Delete user fonts */ + if (p->qmsnumber > 30000 && (p->flags & LOADED)) + printf("%s%d%c%s", DOWNLOAD, p->qmsnumber, p->flags & PORT ? + 'P' : 'L', ENDCMD); + if ((v = getbindingvalue("portraitfont")) && v->class == PROFILE_INTEGER) + portfont = v->value.i; + sanestate(portfont); + fputs(QUICOFF, stdout); + if (Accounting) { +#ifdef TRW + FILE *f; + char badge[51], costcenter[51], chargenumber[51], sessionid[51]; + char s[51], *strcpy(); + + if (!(f = fopen(ACCTFILE, "r"))) + goto getout; + while (fgets(s, 51, f)) + if (strlen(s) > 0) { + if (s[strlen(s) - 1] == '\n') + s[strlen(s) - 1] = '\0'; + switch (s[0]) { + case 'b': + (void)strcpy(badge, &s[1]); + break; + case 'e': + (void)strcpy(costcenter, &s[1]); + break; + case 'u': + (void)strcpy(chargenumber, &s[1]); + break; + case 's': + (void)strcpy(sessionid, &s[1]); + break; + } + } + fprintf(Accting, "%s %s %s %s %d %s@%s\n", badge, costcenter, + chargenumber, sessionid, NumPages, User, Host); + (void)fclose(f); +#else + fprintf(Accting, "%d %s@%s\n", NumPages, User, Host); +#endif + (void)fclose(Accting); + } +getout: + exit(exitstatus); +} diff --git a/dviware/quicspool/src/constants.h_backup b/dviware/quicspool/src/constants.h_backup new file mode 100644 index 0000000000..46c855f596 --- /dev/null +++ b/dviware/quicspool/src/constants.h_backup @@ -0,0 +1,26 @@ +/* $Header: constants.h.backup,v 1.1 88/01/15 13:03:20 simpson Rel $ */ +/* +$Log: constants.h.backup,v $ +Revision 1.1 88/01/15 13:03:20 simpson +initial release + +Revision 0.1 87/12/11 18:30:44 simpson +beta test + +*/ + +#define FIX 1048576 /* 2^20 FIXes = 1 point */ +#define SPOINT 65536 /* 2^16 scaled points (sps) = 1 pt */ +#define RSU 10000000 /* 10000000 RSUs = 1 meter */ +#define PPI 72.27 /* Points per inch */ +#define RESOLUTION 300 /* Pixels per inch */ +#define DVIID 2 +#define DOCILEUSER "--USER--" /* Name of uid to switch to if user is from */ + /* a remote host */ +#define PI 3.14159265358979 +#define HORCATRES 432 /* Horizontal resolution of C/A/T typesetter */ +#define VERCATRES 144 /* Vertical resolution of C/A/T typesetter */ + +#ifdef TRW +#define ACCTFILE ".acctinfo" +#endif diff --git a/dviware/quicspool/src/dev.h b/dviware/quicspool/src/dev.h new file mode 100644 index 0000000000..423d45a3f3 --- /dev/null +++ b/dviware/quicspool/src/dev.h @@ -0,0 +1,49 @@ +/* $Header: dev.h,v 1.1 88/01/15 13:03:23 simpson Rel $ */ +/* +$Log: dev.h,v $ + * Revision 1.1 88/01/15 13:03:23 simpson + * initial release + * + * Revision 0.1 87/12/11 18:30:45 simpson + * beta test + * +*/ +/* @(#)dev.h 1.1 */ +/* + dev.h: characteristics of a typesetter +*/ + +struct dev { + short filesize; /* number of bytes in file, */ + /* excluding dev part */ + short res; /* basic resolution in goobies/inch */ + short hor; /* goobies horizontally */ + short vert; + short unitwidth; /* size at which widths are given, in effect */ + short nfonts; /* number of fonts physically available */ + short nsizes; /* number of sizes it has */ + short sizescale; /* scaling for fractional point sizes */ + short paperwidth; /* max line length in units */ + short paperlength; /* max paper length in units */ + short nchtab; /* number of funny names in chtab */ + short lchname; /* length of chname table */ + short spare1; /* in case of expansion */ + short spare2; +}; + +struct font { /* characteristics of a font */ + char nwfont; /* number of width entries for this font */ + char specfont; /* 1 == special font */ + char ligfont; /* 1 == ligatures exist on this font */ + char spare1; /* unused for now */ + char namefont[10]; /* name of this font (e.g., "R" */ + char intname[10]; /* internal name (=number) on device, in ascii */ +}; + +/* ligatures, ORed into ligfont */ + +#define LFF 01 +#define LFI 02 +#define LFL 04 +#define LFFI 010 +#define LFFL 020 diff --git a/dviware/quicspool/src/df.c_backup b/dviware/quicspool/src/df.c_backup new file mode 100644 index 0000000000..1ef9a3ea8a --- /dev/null +++ b/dviware/quicspool/src/df.c_backup @@ -0,0 +1,1164 @@ +/* TeX driver */ +/* +$Log: df.c.backup,v $ +Revision 1.2 88/02/03 08:52:23 simpson +added tpic support + +Revision 1.1 88/01/15 13:03:27 simpson +initial release + +Revision 0.2 87/12/18 11:39:36 simpson +added void for lint + +Revision 0.1 87/12/11 18:30:46 simpson +beta test + +*/ +#ifndef lint +static char *rcs = "$Header: df.c.backup,v 1.2 88/02/03 08:52:23 simpson Exp $"; +#endif +#include <stdio.h> +#include <signal.h> +#include <assert.h> +#include <math.h> +#include <sys/types.h> +#include <sys/dir.h> +#include <local/profile.h> +#include <local/qms.h> +#include "dvi.h" +#include "constants.h" +#include "fontinfo.h" +#include "fontnode.h" + +/* Cast for accessing LocalInfo */ +#define LI(p) ((struct LocalInfo *)p->localinfo) + +struct Stack { + long h, v, w, x, y, z; +}; + +struct DviNode { + long dvinumber; + struct DviNode *next; +}; + +struct LocalInfo { + long widths[256]; /* RSUs. Font but ! file mag in account */ + short mapsize[2][256];/* Width & height of each char bitmap */ + int qmsheight; /* Height to give QMS printer */ + int qmsbaseline; /* Baseline height to give QMS printer */ + struct DviNode *dvifontnumbers; /* List of #s DVI file uses */ + char pathname[81]; /* Full pathname in file system */ +}; + +double ConvInches; /* RSU->inches. File mag not taken into account */ +char *Whoami; /* argv[0] */ +char Orientation = 'P'; /* P=Portrait, L=Landscape */ +char *Model; /* Model of printer being used */ +char PKName[101]; /* Only used by pkeofsocleanup() */ +char *Xxxstring; /* String found in XXX? command */ +char *Pxxxstring; /* And a pointer used by lexical analyzer */ +char PKDir[101]; /* Location of PK font files */ +int Magnification; /* Magnification file was TeXed at (x1000) */ +int MaxBlocks; /* # of free blocks w/out ram or rom fonts, ovls */ +int CurRamBlocks; /* # of blocks used by ram fonts */ +int CurRomBlocks; /* # of blocks used by rom fonts */ +int DownLoadFNum; /* Number of font currently being downloaded */ +int UserFontCount = 30001; /* User fonts start getting #s from here */ +int Origin[2]; /* Origin of a postprocessor graph in pixels */ +long Numerator, Denominator; /* From .dvi preamble */ +FILE *ReadLine; /* Debugger port tty */ +struct sigvec SigStruct; +struct FontNode *FontList; /* List containing all fnts & their attributes */ +extern char *Host, *User; +extern FILE *Accting; +extern Boolean Accounting; +extern int NumPages; + +main(argc, argv) +int argc; +char *argv[]; +{ + extern char *optarg; + extern int optind; + void qmsfntfree(), cleanup(), dvieofsoexit(), readpreamble(), + seteoffunction(), dvieofsocleanup(), process(); + Boolean found, loadnametable(), setnewid(); + int c; + int *intptr, *tempintptr; + int simplyexit(), callcleanup(); + int romlist[41]; /* List of rom font #s */ + char *strcpy(); +#ifdef DEBUG + char *malloc(), orien; + int i, fontno, size; + struct fontnode *fn; + FILE *f; +#endif + PROFILE_VALUE *v, *getbindingvalue(); + struct qmsram *raminfo; + struct qmsfnt *fntinfo; + struct FontNode *createfontlist(); + struct fontnode *p; + + Whoami = argv[0]; + while ((c = getopt(argc, argv, "x:y:n:h:w:l:i:")) != EOF) + switch (c) { + case 'x': + if (atoi(optarg) > 2550) + Orientation = 'L'; + break; + case 'h': + Host = optarg; + break; + case 'n': + User = optarg; + break; + case 'y': + case 'w': + case 'l': + case 'i': + break; + default: + exit(2); + } + SigStruct.sv_handler = simplyexit; + SigStruct.sv_mask = 0; + SigStruct.sv_onstack = 0; + (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL); + if (optind < argc) { + Accounting = TRUE; + if (!(Accting = fopen(argv[optind], "a"))) { + fprintf(stderr, "%s: cannot open accounting file %s\n", Whoami, + argv[optind]); + Accounting = FALSE; + } + } + if (!(v = getbindingvalue("model")) || v->class != PROFILE_STRING && + v->class != PROFILE_OTHER) { + fprintf(stderr, + "%s: model binding missing or invalid in configuration file\n", + Whoami); + exit(2); + } + Model = v->value.s; + fputs(QUICON, stdout); + printf("%s^Z%s%s", CLEAROVERLAY, CLEARAOVERLAY, ENDCMD); + fputs(QUICOFF, stdout); + (void)fflush(stdout); + if (!(v = getbindingvalue("readline")) || v->class != PROFILE_STRING && + v->class != PROFILE_OTHER) { + fprintf(stderr, + "%s: readline binding missing or invalid in configuration file\n", + Whoami); + exit(2); + } + if (!(ReadLine = fopen(v->value.s, "r"))) { + fprintf(stderr, "%s: could not open %s for reading\n", Whoami, + v->value.s); + exit(2); + } +#ifdef DEBUG + raminfo = (struct qmsram *)malloc((unsigned)sizeof(struct qmsram)); + raminfo->TR = 401; + raminfo->AR = 387; + raminfo->FR = 13; + raminfo->OR = 0; +#else + qmsopen(fileno(stdout), fileno(ReadLine)); + if (!(raminfo = qmsram())) { + fprintf(stderr, "%s: could not get printer ram info\n", Whoami); + exit(2); + } +#endif + MaxBlocks = raminfo->AR + raminfo->FR; + /* Save 5 blocks for filling with tpic */ + MaxBlocks -= 5; +#ifdef DEBUG + fntinfo = (struct qmsfnt *)malloc((unsigned)sizeof(struct qmsfnt)); + fntinfo->ram = fntinfo->rom = NULL; + for (i = 0; i < 13; i++) { + switch (i) { + case 0: + fontno = 521; + orien = 'L'; + break; + case 1: + fontno = 522; + orien = 'L'; + break; + case 2: + fontno = 523; + orien = 'L'; + break; + case 3: + fontno = 524; + orien = 'L'; + break; + case 4: + fontno = 1100; + orien = 'P'; + break; + case 5: + fontno = 1103; + orien = 'P'; + break; + case 6: + fontno = 1200; + orien = 'P'; + break; + case 7: + fontno = 1204; + orien = 'P'; + break; + case 8: + fontno = 1217; + orien = 'L'; + case 9: + fontno = 7009; + orien = 'P'; + break; + case 10: + fontno = 7010; + orien = 'P'; + break; + case 11: + fontno = 7036; + orien = 'P'; + break; + case 12: + fontno = 7037; + orien = 'P'; + break; + } + fn = (struct fontnode *)malloc((unsigned)sizeof(struct fontnode)); + fn->next = fntinfo->rom, fntinfo->rom = fn; + fn->orientation = orien; + fn->number = fontno; + fn->bytes = 1024; /* Rom fonts occupy one block */ + fn->version = '0'; + fn->class = '1'; + } + /* For testing, ramfonts contains the already loaded fonts. It should + * consist of lines containing two numbers and a letter, the first being + * the font number, the second being the font size, and the third letter + * is an orientation. The orientation should be the character immediately + * after the size of the font. + */ + if (f = fopen("ramfonts", "r")) { /* File is optional for testing */ + while (fscanf(f, "%d%d%c", &fontno, &size, &orien) == 3) + { + fn = (struct fontnode *)malloc((unsigned)sizeof(struct fontnode)); + fn->next = fntinfo->ram, fntinfo->ram = fn; + fn->orientation = orien; + fn->number = fontno; + fn->bytes = size; + fn->version = '0'; + fn->class = '1'; + raminfo->AR -= CEILING(size / 1024.0); + raminfo->FR += CEILING(size / 1024.0); + } + fclose(f); + } +#else + if (!(fntinfo = qmsfnt())) { + fprintf(stderr, "%s: could not get printer font info\n", Whoami); + exit(2); + } +#endif + for (CurRomBlocks = 0, p = fntinfo->rom; p; p = p->next) + CurRomBlocks += CEILING(p->bytes / (double)1024); + CurRamBlocks = raminfo->FR - CurRomBlocks; + /* Make an array of rom font #s */ + for (p = fntinfo->rom, intptr = romlist; p; p = p->next) { + for (tempintptr = romlist, found = FALSE; tempintptr < intptr; + tempintptr++) + if (*tempintptr == p->number) + found = TRUE; + if (!found) + *intptr++ = p->number; + } + *intptr = 0; + if (EQ(Model, "QMS800")) + (void)strcpy(PKDir, "--PKDIR1--"); + else + (void)strcpy(PKDir, "--PKDIR2--"); + if (!loadnametable(PKDir, romlist, 1)) { + fprintf(stderr, "%s: could not open font directory %s\n", Whoami, + PKDir); + exit(2); + } + FontList = createfontlist(fntinfo); + qmsfntfree(fntinfo); + if (!setnewid(Host, User)) { + fprintf(stderr, "%s: could not change user id to %s\n", Whoami, + User); + exit(2); /* This is fatal, bud. */ + } + seteoffunction(dvieofsoexit); + readpreamble(); + SigStruct.sv_handler = callcleanup; + (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL); + fputs(QUICON, stdout); + if (Orientation == 'P') + fputs(PORTRAIT, stdout); + else + fputs(LANDSCAPE, stdout); + printf("%s%c%c", TEXTPROC, '0', '0'); + printf("%s00000%05d", INITMARGVERT, Orientation == 'P' ? 11 * 1000 : + (int)(8.5 * 1000)); + printf("%s00000%05d", INITMARGHORZ, Orientation == 'P' ? (int)(8.5 * + 1000) : 11 * 1000); + printf("%s0000", CHARSPACING); + fputs(FREEOFF, stdout); + seteoffunction(dvieofsocleanup); + process(); + cleanup(FontList, SUCCEED); +} + +/* Reads the info in the DVI preamble */ +void readpreamble() +{ + int i, k; + long integer(); + unsigned long uinteger(); + + if (cgetchar() != PRE) { + fprintf(stderr, "%s: input file is not a DVI file\n", Whoami); + exit(2); + } + if (cgetchar() != DVIID) { + fprintf(stderr, "%s: wrong version of DVI file \n", Whoami); + exit(2); + } + Numerator = uinteger(stdin, 4); + Denominator = uinteger(stdin, 4); + Magnification = integer(stdin, 4); + k = cgetchar(); /* Ignore comment */ + for (i = 0; i < k; i++) + (void)cgetchar(); + ConvInches = 1 / 100000.0 / 2.54; + /* RSU 1m 100cm 1inch n inches */ + /* x --------- x ----- x ------ = */ + /* 10^7 RSUs 1m 2.54cm */ +} + +/* Main routine that interprets the DVI file */ +void process() +{ + unsigned long uinteger(), ulk, uli; + struct FontNode *curfontnode = NULL, *getdvifontnode(), *tempcurfontnode; + struct Stack *tempstack; + Boolean download(), makeroom(), fontselected = FALSE; + int ch, ldirectory, lfontname, i; + long dvifontnum, dvichecksum, scalefactor, designsize, curfontnum, + integer(), a, b; + char directory[256], fontname[256], *push(), *pop(), *malloc(); + void fonttolist(), adjust(), endoflist(); + long h, v, w, x, y, z; /* In RSUs. Mag not taken in account */ + long realhpxl, realvpxl; /* Real h & v in printer in pixels */ + long virthpxl, virtvpxl; /* Virtual h & v current point in */ + /* pixels. Mag is taken in account */ + + for (ch = cgetchar(); ch != BOP; ch = cgetchar()) + switch (ch) { + case NOP: + break; + case FNTDEF1: + case FNTDEF2: + case FNTDEF3: + case FNTDEF4: + dvifontnum = integer(stdin, ch - FNTDEF1 + 1); + dvichecksum = integer(stdin, 4); + scalefactor = integer(stdin, 4); + designsize = integer(stdin, 4); + ldirectory = cgetchar(); + lfontname = cgetchar(); + for (i = 0; i < ldirectory; i++) + directory[i] = cgetchar(); + directory[i] = '\0'; + for (i = 0; i < lfontname; i++) + fontname[i] = cgetchar(); + fontname[i] = '\0'; + fonttolist(dvifontnum, dvichecksum, scalefactor, designsize, + directory, fontname); + break; + default: +#ifndef lint + assert(FALSE); +#else + ; +#endif + cleanup(FontList, 2); + } + while (ch == BOP) { + for (i = 0; i < 10; i++) + (void)integer(stdin, 4); + (void)uinteger(stdin, 4); /* Pointer to previous page */ + virthpxl = virtvpxl = realhpxl = realvpxl = h = v = w = x = y = z = 0; + for (ch = cgetchar(); ch != EOP; ch = cgetchar()) { + virthpxl = ROUND(h*ConvInches*RESOLUTION*(Magnification/1000.0)); + virtvpxl = ROUND(v*ConvInches*RESOLUTION*(Magnification/1000.0)); + if (SETCHAR0 <= ch && ch < 128) { + /* The following statement will only be true if the first + * font in the dvi file was not found at any magnification. + * In this case, skip this character since we don't know + * how to increment the virtual or real pixel locations! + * The true coordinates will probably be reset when TeX + * pops the stack at the beginning of a line. + */ + if (!curfontnode || !curfontnode->localinfo) + continue; + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v); + if (!(curfontnode->flags & LOADED)) { + if (!makeroom(FontList, MaxBlocks, &CurRamBlocks, + CurRomBlocks, curfontnode->blocksize)) { + fprintf(stderr, + "%s: could not free %d blocks for font %s\n", Whoami, + curfontnode->blocksize, LI(curfontnode)->pathname); + goto trytocontinue1; + } + if (!download(curfontnode)) + goto trytocontinue1; + realhpxl = realvpxl = 0; + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v); + } + if (!fontselected) { + printf("%s%d%s", DEFFONT, curfontnode->qmsnumber, ENDCMD); + fontselected = TRUE; + } + /* SliTeX fonts have width but no bitmap. Unfortunately the + * QMS will not print (or download) a character with width and + * no bitmap so we must not print characters that are not in + * the font. If you do, you will get the lowest character in + * the font. + */ +trytocontinue1: if (LI(curfontnode)->mapsize[0][ch] != 0 && + LI(curfontnode)->mapsize[1][ch] != 0) { + if (ch == '^' || ch <= 32 || ch >= 127) + printf("%s%02X", SPECIAL, ch); + else + (void)putchar(ch); + realhpxl += ROUND(LI(curfontnode)->widths[ch] * + (Magnification / 1000.0) * ConvInches * RESOLUTION); + } + h += LI(curfontnode)->widths[ch]; + } else if (FNTNUM0 <= ch && ch < FNT1) { + curfontnum = ch - FNTNUM0; + if (!(tempcurfontnode = getdvifontnode(FontList, + curfontnum, Orientation))) + continue; /* Font file was not found during FNTDEF */ + curfontnode = tempcurfontnode; + endoflist(&FontList, curfontnode); + fontselected = FALSE; + putchar('\r'); /* Ends the pass */ + printf("%s00000%s", TAB, ENDCMD); + printf("%s00000%s", JUSTIFYMARGIN, ENDCMD); + realhpxl = realvpxl = 0; + } else switch (ch) { + case SET1: + case SET2: + case SET3: + case SET4: + ch = uinteger(stdin, ch - SET1 + 1); + assert(0 <= ch && ch <= 255); + if (!curfontnode || !curfontnode->localinfo) + continue; + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v); + if (!(curfontnode->flags & LOADED)) { + if (!makeroom(FontList, MaxBlocks, &CurRamBlocks, + CurRomBlocks, curfontnode->blocksize)) { + fprintf(stderr, + "%s: could not free %d blocks for font %s\n", + Whoami, curfontnode->blocksize, + LI(curfontnode)->pathname); + goto trytocontinue2; + } + if (!download(curfontnode)) + goto trytocontinue2; + realhpxl = realvpxl = 0; + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v); + } + if (!fontselected) { + printf("%s%d%s", DEFFONT, curfontnode->qmsnumber, + ENDCMD); + fontselected = TRUE; + } +trytocontinue2: if (LI(curfontnode)->mapsize[0][ch] != 0 && + LI(curfontnode)->mapsize[1][ch] != 0) { + if (ch == '^' || ch <= 32 || ch >= 127) + printf("%s%02X", SPECIAL, ch); + else + (void)putchar(ch); + realhpxl += ROUND(LI(curfontnode)->widths[ch] * + (Magnification / 1000.0) * ConvInches * RESOLUTION); + } + h += LI(curfontnode)->widths[ch]; + break; + case SETRULE: + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v); + a = integer(stdin, 4); + b = integer(stdin, 4); + if (a > 0 && b > 0) { + printf("%s-%05d", JUSTIFYRELATIVE, ROUND(a / + (double)SPOINT / PPI * (double)Magnification)); + printf("%s%05d%05d", LINE, + ROUND(b/(double)SPOINT/PPI*(double)Magnification), + ROUND(a/(double)SPOINT/PPI*(double)Magnification)); + printf("%s+%05d", JUSTIFYRELATIVE, ROUND(a / + (double)SPOINT / PPI * (double)Magnification)); + realhpxl += ROUND(b / (double)SPOINT / PPI * + RESOLUTION * (Magnification / 1000.0)); + } + h += ROUND(b * (Numerator / (double)Denominator)); + break; + case PUT1: + case PUT2: + case PUT3: + case PUT4: + ch = uinteger(stdin, ch - PUT1 + 1); + assert(0 <= ch && ch <= 255); + if (!curfontnode || !curfontnode->localinfo) + continue; + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v); + if (!(curfontnode->flags & LOADED)) { + if (!makeroom(FontList, MaxBlocks, &CurRamBlocks, + CurRomBlocks, curfontnode->blocksize)) { + fprintf(stderr, + "%s: could not free %d blocks for font %s\n", + Whoami, curfontnode->blocksize, + LI(curfontnode)->pathname); + goto trytocontinue3; + } + if (!download(curfontnode)) + goto trytocontinue3; + realhpxl = realvpxl = 0; + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v); + } + if (!fontselected) { + printf("%s%d%s", DEFFONT, curfontnode->qmsnumber, + ENDCMD); + fontselected = TRUE; + } +trytocontinue3: if (LI(curfontnode)->mapsize[0][ch] != 0 && + LI(curfontnode)->mapsize[1][ch] != 0) { + if (ch == '^' || ch <= 32 || ch >= 127) + printf("%s%02X", SPECIAL, ch); + else + (void)putchar(ch); + realhpxl += ROUND(LI(curfontnode)->widths[ch] * + (Magnification / 1000.0) * ConvInches * RESOLUTION); + } + break; + case PUTRULE: + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v); + a = integer(stdin, 4); + b = integer(stdin, 4); + if (a > 0 && b > 0) { + printf("%s-%05d", JUSTIFYRELATIVE, ROUND(a / + (double)SPOINT / PPI * (double)Magnification)); + printf("%s%05d%05d", LINE, + ROUND(b/(double)SPOINT/PPI*(double)Magnification), + ROUND(a/(double)SPOINT/PPI*(double)Magnification)); + printf("%s+%05d", JUSTIFYRELATIVE, ROUND(a / + (double)SPOINT / PPI * (double)Magnification)); + realhpxl += ROUND(b / (double)SPOINT / PPI * + RESOLUTION * (Magnification / 1000.0)); + } + break; + case NOP: + break; + case PUSH: + tempstack = (struct Stack *)malloc((unsigned)sizeof( + struct Stack)); + tempstack->h = h, tempstack->v = v, tempstack->w = w, + tempstack->x = x, tempstack->y = y, tempstack->z = z; + (void)push((char *)tempstack); + break; + case POP: + tempstack = (struct Stack *)pop(); + assert(tempstack); + h = tempstack->h, v = tempstack->v, w = tempstack->w, + x = tempstack->x, y = tempstack->y, z = tempstack->z; + free((char *)tempstack); + break; + case RIGHT1: + case RIGHT2: + case RIGHT3: + case RIGHT4: + h += integer(stdin, ch - RIGHT1 + 1) * (Numerator / + (double)Denominator); + break; + case W0: +horw: h += w; + break; + case W1: + case W2: + case W3: + case W4: + w = integer(stdin, ch - W1 + 1) * (Numerator / + (double)Denominator); + goto horw; + case X0: +horx: h += x; + break; + case X1: + case X2: + case X3: + case X4: + x = integer(stdin, ch - X1 + 1) * (Numerator / + (double)Denominator); + goto horx; + case DOWN1: + case DOWN2: + case DOWN3: + case DOWN4: + v += integer(stdin, ch - DOWN1 + 1) * (Numerator / + (double)Denominator); + break; + case Y0: +very: v += y; + break; + case Y1: + case Y2: + case Y3: + case Y4: + y = integer(stdin, ch - Y1 + 1) * (Numerator / + (double)Denominator); + goto very; + case Z0: +verz: v += z; + break; + case Z1: + case Z2: + case Z3: + case Z4: + z = integer(stdin, ch - Z1 + 1) * (Numerator / + (double)Denominator); + goto verz; + case FNT1: + case FNT2: + case FNT3: + case FNT4: + curfontnum = uinteger(stdin, ch - FNT1 + 1); + if (!(tempcurfontnode = getdvifontnode(FontList, + curfontnum, Orientation))) + continue; + curfontnode = tempcurfontnode; + endoflist(&FontList, curfontnode); + fontselected = FALSE; + putchar('\r'); /* Ends the pass */ + printf("%s00000%s", TAB, ENDCMD); + printf("%s00000%s", JUSTIFYMARGIN, ENDCMD); + realhpxl = realvpxl = 0; + break; + case XXX1: + case XXX2: + case XXX3: + case XXX4: + ulk = uinteger(stdin, ch - XXX1 + 1); + Pxxxstring = Xxxstring = malloc((unsigned)(ulk + 1)); + for (uli = 0; uli < ulk; uli++) + Xxxstring[uli] = cgetchar(); + Xxxstring[uli] = '\0'; + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v); + Origin[0] = virthpxl + RESOLUTION, Origin[1] = virtvpxl + + RESOLUTION; + (void)yyparse(); + free(Xxxstring); + fputs(QUICON, stdout); + if (Orientation == 'P') + fputs(PORTRAIT, stdout); + else + fputs(LANDSCAPE, stdout); + printf("%s%c%c", TEXTPROC, '0', '0'); + printf("%s00000%05d", INITMARGVERT, Orientation == 'P' ? + 11 * 1000 : (int)(8.5 * 1000)); + printf("%s00000%05d", INITMARGHORZ, Orientation == 'P' ? + (int)(8.5 * 1000) : 11 * 1000); + printf("%s0000", CHARSPACING); + realhpxl = realvpxl = 0; + break; + case FNTDEF1: + case FNTDEF2: + case FNTDEF3: + case FNTDEF4: + dvifontnum = integer(stdin, ch - FNTDEF1 + 1); + dvichecksum = integer(stdin, 4); + scalefactor = integer(stdin, 4); + designsize = integer(stdin, 4); + ldirectory = cgetchar(); + lfontname = cgetchar(); + for (i = 0; i < ldirectory; i++) + directory[i] = cgetchar(); + directory[i] = '\0'; + for (i = 0; i < lfontname; i++) + fontname[i] = cgetchar(); + fontname[i] = '\0'; + fonttolist(dvifontnum, dvichecksum, scalefactor, + designsize, directory, fontname); + break; + default: /* Bad DVI command */ +#ifndef lint + assert(FALSE); +#else + ; +#endif + cleanup(FontList, 2); + } + } + NumPages++; + printf("%s", FORMFEED); + for (ch = cgetchar(); ch != BOP && ch != POST; ch = cgetchar()) + switch (ch) { + case NOP: + break; + case FNTDEF1: + case FNTDEF2: + case FNTDEF3: + case FNTDEF4: + dvifontnum = integer(stdin, ch - FNTDEF1 + 1); + dvichecksum = integer(stdin, 4); + scalefactor = integer(stdin, 4); + designsize = integer(stdin, 4); + ldirectory = cgetchar(); + lfontname = cgetchar(); + for (i = 0; i < ldirectory; i++) + directory[i] = cgetchar(); + directory[i] = '\0'; + for (i = 0; i < lfontname; i++) + fontname[i] = cgetchar(); + fontname[i] = '\0'; + fonttolist(dvifontnum, dvichecksum, scalefactor, + designsize, directory, fontname); + break; + default: +#ifndef lint + assert(FALSE); +#else + ; +#endif + cleanup(FontList, 2); + } + } + while (getchar() != EOF) + ; +} + + +/* Returns the full pathname of the pk file found or NULL if not found. + * The algorithm is as follows: + * Create a new path, say TEXFONTS*, which is equal to $TEXFONTS:PKDir + * if there is a directory name in the DVI file { + * look in that directory for the font at any magnification + * if found { + * select this font + * return it + * } + * } + * look in TEXFONTS* directories consecutively for font with closest + * magnification + * if no font matches, return NULL + */ +char *findpkfont(directory, fontname, designsize, scalefactor) +char *directory; +char *fontname; +long designsize, scalefactor; +{ + int closestnumber = MAX_INTEGER; + int desiredmagnification = ROUND(RESOLUTION * + ((double)scalefactor / designsize) * (Magnification / + 1000.0)); + int dirdsize, dirmag; + Boolean extractinfo(); + static char returnvalue[101]; + char dirfname[81], dirsfname[81], hostname[81], component[81]; + char fontpaths[201], *strcpy(), *nextcomponent(); + char *p, *comp, *fgetenv(), *expandtilde(), *expandhome(); + DIR *dirp; + struct direct *direntry; + + returnvalue[0] = '\0'; + (void)gethostname(hostname, 80); + if (!EQ(hostname, Host) || !(p = fgetenv("TEXFONTS", User))) + (void)strcpy(fontpaths, PKDir); + else + (void)sprintf(fontpaths, "%s:%s", p, PKDir); + if (directory && strlen(directory) > 0) { + if (dirp = opendir(directory)) { + for (direntry = readdir(dirp); direntry; direntry = + readdir(dirp)) { + if (direntry->d_namlen < 5 || !extractinfo(direntry->d_name, + dirfname, dirsfname, &dirdsize, &dirmag) || !EQ(dirfname, + fontname)) + continue; + if (ABS(dirmag - desiredmagnification) < closestnumber) { + closestnumber = ABS(dirmag - desiredmagnification); + (void)sprintf(returnvalue, "%s%s", directory, + direntry->d_name); + } + } + closedir(dirp); + if (strlen(returnvalue) > 0) + return returnvalue; + } + } + for (p = &fontpaths[0]; comp = nextcomponent(&p); ) { + (void)strcpy(component, comp); + (void)expandtilde(component); + (void)expandhome(component); + if (dirp = opendir(component)) { + for (direntry = readdir(dirp); direntry; direntry = readdir(dirp)) + { + if (direntry->d_namlen < 5 || !extractinfo(direntry->d_name, + dirfname, dirsfname, &dirdsize, &dirmag) || !EQ(dirfname, + fontname)) + continue; + if (ABS(dirmag - desiredmagnification) < closestnumber) { + closestnumber = ABS(dirmag - desiredmagnification); + (void)sprintf(returnvalue, "%s/%s", component, + direntry->d_name); + } + } + closedir(dirp); + } + } + if (strlen(returnvalue) > 0) + return returnvalue; + return NULL; +} + +/* Adjusts the real current position to the virtual current position */ +void adjust(realh, realv, virth, virtv, h, v) +long *realh, *realv; +long virth, virtv; +long h, v; +{ + if (*realh != virth + RESOLUTION) { + printf("%s%05d%s", TAB, ROUND(h * ConvInches * Magnification) + 1000, + ENDCMD); /* Add 1000 since the origin is (1in,1in) */ + *realh = virth + RESOLUTION; + } + if (*realv != virtv + RESOLUTION) { + printf("%s%05d%s", JUSTIFYMARGIN, ROUND(v * ConvInches * + Magnification) + 1000, ENDCMD); + *realv = virtv + RESOLUTION; + } +} + +/* Adds a new font to the font list. The width info, mapsize, qmsheight, + * qmsbaseline, pathname, blocksize and dvifontnumber in the FontNode + * structure and LocalInfo structure are filled in also. If the font is + * loaded on startup, the blocksize is left as is; otherwise, the blocksize + * is estimated. + */ +void fonttolist(fontnumber, dvichecksum, scalefactor, designsize, directory, +fontname) +long fontnumber; +long dvichecksum; +long scalefactor, designsize; +char *directory, *fontname; +{ + struct DviNode *d; + struct FontInfo *fi, *getfontinfo(); + struct FontNode *fn, *getfontnode(); + char *fullfontpath, *findpkfont(), *tail(); + void cleanup(), pkeofsocleanup(), seteoffunction(), + dvieofsocleanup(); + int qmsfontnum, i; + Boolean found; + + if (!(fullfontpath = findpkfont(directory, fontname, designsize, + scalefactor))) { + fprintf(stderr, "%s: could not find font %s anywhere\n", Whoami, + fontname); + return; /* Try to continue */ + } + if (EQN(PKDir, fullfontpath, strlen(PKDir)) && fullfontpath[strlen(PKDir)] + == '/' && EQ(&fullfontpath[strlen(PKDir)+1], tail(fullfontpath))) + qmsfontnum = getnumfromtable(tail(fullfontpath)); + else /*tail(fullfontpath) ! necessarily == fontname if exact size !found*/ + qmsfontnum = UserFontCount++; + assert(qmsfontnum > 0); + if (!(fn = getfontnode(FontList, qmsfontnum, Orientation))) { + bzero((char *)(fn = (struct FontNode *)malloc((unsigned)sizeof(struct + FontNode))), sizeof(struct FontNode)); + fn->next = FontList, FontList = fn; + } + if (!fn->localinfo) + bzero(fn->localinfo = malloc((unsigned)sizeof(struct LocalInfo)), + sizeof(struct LocalInfo)); + fn->flags |= RAM; + if (Orientation == 'P') + fn->flags |= PORT; + fn->qmsnumber = qmsfontnum; + (void)strcpy(LI(fn)->pathname, fullfontpath); + for (d = LI(fn)->dvifontnumbers, found = FALSE; d && !found; d = d->next) + if (d->dvinumber == fontnumber) + found = TRUE; + if (!found) { + d = (struct DviNode *)malloc(sizeof(struct DviNode)); + d->next = LI(fn)->dvifontnumbers, LI(fn)->dvifontnumbers = d; + d->dvinumber = fontnumber; + } + (void)strcpy(PKName, fullfontpath); + seteoffunction(pkeofsocleanup); + if (!(fi = getfontinfo(fullfontpath, (EQ(Model, "QMS800") || + EQ(Model, "QMS1500")) && Orientation == 'P' || (!EQ(Model, "QMS800") && + !EQ(Model, "QMS1500")) && Orientation == 'L' ? 'X' : 'Y'))) { + fprintf(stderr, "%s: cannot open or invalid font file %s\n", Whoami, + fullfontpath); + fn->flags |= LOADED; /* Try to continue */ + fn->blocksize = 0; + return; + } + seteoffunction(dvieofsocleanup); + LI(fn)->qmsheight = fi->qmsheight; + LI(fn)->qmsbaseline = fi->qmsbaseline; + if (!(fn->flags & PRELOADED)) + fn->blocksize = fi->blocksize; + for (i = 0; i < 256; i++) { + LI(fn)->widths[i] = ROUND(fi->chararray[i].tfm * ((fi->ds / + (double)FIX) / FIX) * (2.54 / PPI * 100000) * ((fi->hppp / + (double)SPOINT * PPI / RESOLUTION) / (Magnification / 1000.0))); + LI(fn)->mapsize[0][i] = fi->chararray[i].w; + LI(fn)->mapsize[1][i] = fi->chararray[i].h; + } +/* fi->chararray[i].tfm is in units of FIXes/designsize. fi->hppp is in units + * of scaled points times pixels/point. Convert the width into RSUs with only + * font magnification taken into account by the following formulas: + * + * tfm designsize + * x ---------- = width in points + * FIX + * + * width 1inch 2.54cm 1m 10^7RSUs + * in x -------- x ------ x ----- x -------- = width in RSUs + * points 72.27pts 1inch 100cm 1m + * + * hppp PPI + * ------ x = Resolution designed for (the number before "pk" in the + * SPOINT file name) + * + * Multiplying the width in RSUs by the number before the "pk" in the file + * name yields the width in RSUs with font and file magnification taken into + * account. Dividing by the file magnification yields the width with only + * the font magnification taken into account. + */ + if (dvichecksum != 0 && fi->cs != 0) + if (dvichecksum != fi->cs) + fprintf(stderr, + "%s: DVI checksum (O%lo) != PK checksum (O%lo) in %s\n", + Whoami, dvichecksum, fi->cs, LI(fn)->pathname); +} + +/* Downloads a font */ +Boolean download(fn) +struct FontNode *fn; +{ + struct CharInfo *ci; + char *tail(), *strcpy(); + void resetpkfile(), seteoffunction(), + downloadpkeofsocleanup(), dvieofsocleanup(); + int downloadinterrupt(), callcleanup(); + int downloadtype, result, i, truebyteswide, bytestooutput, + row, bytes; + + if (!fn || fn->flags & LOADED || !(fn->flags & RAM) || (fn->flags & PORT ? + 'P' : 'L') != Orientation) + return FALSE; + resetpkfile(); + downloadtype = ((EQ(Model, "QMS800") || EQ(Model, "QMS1500")) && + Orientation == 'P' || (!EQ(Model, "QMS800") && !EQ(Model, "QMS1500")) + && Orientation == 'L' ? 'X' : 'Y'); + DownLoadFNum = fn->qmsnumber; + (void)sigblock(SIGINT); /* Temporarily block interrupts */ + SigStruct.sv_handler = downloadinterrupt; + (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL); + (void)strcpy(PKName, LI(fn)->pathname); + seteoffunction(downloadpkeofsocleanup); + /* #defining ASCIILOAD causes ASCII characters to be used for the download + * sequence. Twice as many characters must be sent but it is useful for + * looking at the output when debugging. Also, you can actually see the + * bitmaps in the output. ASCII loading must be used when you can't get + * hardware flow control to work. Far out. + */ +#ifdef ASCIILOAD + fputs(FREEFORM, stdout); +#else + fputs(EIGHTBITON, stdout); +#endif + printf("%s%05d%c0%-4.4s%03d%03dT", DOWNLOAD, fn->qmsnumber, Orientation, + tail(LI(fn)->pathname), LI(fn)->qmsheight, LI(fn)->qmsbaseline); + (void)sigsetmask(sigblock(0) & ~SIGINT); /* Unblock interrupts */ + while ((result = getnextcharinfo(LI(fn)->pathname, downloadtype, &ci)) != + 1) + switch (result) { + case 2: + fprintf(stderr, "%s: could not open %s\n", Whoami, + LI(fn)->pathname); + return FALSE; + case 3: + fprintf(stderr, "%s: %s is not a PK file\n", Whoami, + LI(fn)->pathname); + return FALSE; + case 4: + fprintf(stderr, "%s: %s PK version is incorrect\n", Whoami, + LI(fn)->pathname); + return FALSE; + case 0: /* Ok. Got a bitmap */ + if (ci->h == 0 || ci->w == 0) + continue; + putchar(','); + printf("%02X%03d", ci->cc, ROUND(LI(fn)->widths[ci->cc] * + (Magnification / 1000.0) * ConvInches * RESOLUTION)); + if (downloadtype == 'X') { + printf("%03d%03d", ci->h, ci->w); + printf("%c%03d", LI(fn)->qmsbaseline - ci->voff >= 0 ? '+' + : '-', ABS(LI(fn)->qmsbaseline - ci->voff)); + printf("%c%03d", -ci->hoff >= 0 ? '+' : '-', ABS(-ci->hoff)); + } else { + printf("%03d%03d", ci->w, ci->h); + printf("%c%03d", -ci->hoff >= 0 ? '+' : '-', ABS(ci->hoff)); + printf("%c%03d", (LI(fn)->qmsheight - LI(fn)->qmsbaseline) - + (ci->h - ci->voff) >= 0 ? '+' : '-', ABS((LI(fn)->qmsheight + - LI(fn)->qmsbaseline) - (ci->h - ci->voff))); + i = ci->w, ci->w = ci->h, ci->h = i; /* Swaparoo! */ + } + truebyteswide = ci->w + 7 >> 3; /* >> divides by 8 */ + bytestooutput = (ci->w + 15 >> 4) * 2; /* >> divides by 16 */ +#ifdef ASCIILOAD + for (row = 0; row < ci->h; row++) { +#else + for (row = 0; row < ci->h; row++) +#endif + for (bytes = 0; bytes < bytestooutput; bytes++) { + if (bytes == truebyteswide - 1) + *(ci->bitmap + row * truebyteswide + bytes) &= + 0xFF<<7-(ci->w+7)%8; + if (bytes < truebyteswide) { + i = *(ci->bitmap + row * truebyteswide + bytes) & + 0xFF; +#ifdef ASCIILOAD + printf("%c%c", "0123456789ABCDEF"[i >> 4], + "0123456789ABCDEF"[i & 0xF]); +#else + if (i == '^') + printf("^^"); + else + (void)putchar(i); +#endif + } else +#ifdef ASCIILOAD + printf("00"); +#else + (void)putchar(0); +#endif + } +#ifdef ASCIILOAD + putchar('\n'); + } +#endif + break; + } /* End switch */ +#ifdef ASCIILOAD + printf("%s%s", ENDCMD, FREEOFF); +#else + printf("%s%s", ENDCMD, EIGHTBITOFF); +#endif + putchar('\r'); /* Ends the pass */ + (void)sigblock(SIGINT); + printf("%s00000%s", TAB, ENDCMD); + printf("%s00000%s", JUSTIFYMARGIN, ENDCMD); + SigStruct.sv_handler = callcleanup; + (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL); + seteoffunction(dvieofsocleanup); + CurRamBlocks += fn->blocksize; + fn->flags |= LOADED; + (void)sigsetmask(sigblock(0) & ~SIGINT); + return TRUE; +} + +/* Returns a pointer to a font on the font list using the DVI number; NULL + * if not found. + */ +struct FontNode *getdvifontnode(head, dvinumber, orientation) +struct FontNode *head; +long dvinumber; +int orientation; +{ + struct FontNode *p; + struct DviNode *d; + + for (p = head; p; p = p->next) + if (p->flags & RAM && (p->flags & PORT ? 'P' : 'L') == orientation + && p->localinfo && LI(p)->dvifontnumbers) + for (d = LI(p)->dvifontnumbers; d; d = d->next) + if (d->dvinumber == dvinumber) + return p; + return NULL; +} + +/* The following are routines called when a SIGINT is received or EOF is + * unexpectedly encountered when reading a file. + */ +simplyexit() +{ + exit(SUCCEED); +} + +callcleanup() +{ + void cleanup(); + + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, SUCCEED); /* Interrupting a program is not an error */ +} + +void dvieofsoexit() +{ + fprintf(stderr, "%s: unexpected EOF when reading DVI file\n", Whoami); + exit(2); +} + +void dvieofsocleanup() +{ + fprintf(stderr, "%s: unexpected EOF when reading DVI file\n", Whoami); + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, 2); +} + +void pkeofsocleanup() +{ + fprintf(stderr, "%s: unexpected EOF in PK file %s\n", Whoami, PKName); + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, 2); +} + +void downloadpkeofsocleanup() +{ + fputs(ENDCMD, stdout); +#ifdef ASCIILOAD + fputs(FREEOFF, stdout); +#else + fputs(EIGHTBITOFF, stdout); +#endif + printf("%s%05d%c%s", DOWNLOAD, DownLoadFNum, Orientation, ENDCMD); + pkeofsocleanup(); +} + +downloadinterrupt() +{ + fputs(ENDCMD, stdout); +#ifdef ASCIILOAD + fputs(FREEOFF, stdout); +#else + fputs(EIGHTBITOFF, stdout); +#endif + printf("%s%05d%c%s", DOWNLOAD, DownLoadFNum, Orientation, ENDCMD); + callcleanup(); +} + + +/* Lex and Yacc routines to parse \special command string */ +#include "xxx.c" diff --git a/dviware/quicspool/src/ditroff.backup b/dviware/quicspool/src/ditroff.backup new file mode 100644 index 0000000000..ef044e2d99 --- /dev/null +++ b/dviware/quicspool/src/ditroff.backup @@ -0,0 +1,49 @@ +#! /bin/sh +# $Header: ditroff.backup,v 1.1 88/01/15 13:03:40 simpson Rel $ +# $Log: ditroff.backup,v $ +#Revision 1.1 88/01/15 13:03:40 simpson +#initial release +# +#Revision 0.1 87/12/11 18:30:49 simpson +#beta test +# +# We must give the -T flag to ditroff so it knows to look in +# --DIFONT--. We also must parse the ditroff and lpr flags. +troffflags=-Tqms +lprflags=-n +while [ $# -gt 0 ];do + case $1 in +# Begin of ditroff flags + -o* | -n* | -m* | -i | -q | -z | -a | -T*) + troffflags="$troffflags $1" + shift + ;; +# Begin of lpr flags + -P* | -\#* | -w* | -l | -t | -d | -g | -v | -c | -r | -h | -s | -L) + lprflags="$lprflags $1" + shift + ;; + -C | -J | -1 | -2 | -3 | -4) + lprflags="$lprflags $1 $2" + shift; shift + ;; +# Troff extension flags + -R*) + troffflags="$troffflags `echo $1|sed s/-R/-r/`" + shift + ;; + -M) + lprflags="$lprflags -m" + shift + ;; +# Any remaining flags go to troff + -*) + troffflags="$troffflags $1" + shift + ;; + *) + break + ;; + esac +done +troff $troffflags $* | glpr $lprflags diff --git a/dviware/quicspool/src/dumpdesc.c b/dviware/quicspool/src/dumpdesc.c new file mode 100644 index 0000000000..4b249de919 --- /dev/null +++ b/dviware/quicspool/src/dumpdesc.c @@ -0,0 +1,177 @@ +#ifndef lint +static char *rcs = "$Header: dumpdesc.c,v 1.1 88/01/15 13:03:43 simpson Rel $"; +#endif +/* +$Log: dumpdesc.c,v $ + * Revision 1.1 88/01/15 13:03:43 simpson + * initial release + * + * Revision 0.1 87/12/11 18:30:50 simpson + * beta test + * +*/ +#include <stdio.h> +#include <local/standard.h> +#include "dev.h" + +char EOFName[81]; +char *WhoAmI; +char *Usage = "Usage: %s DESCfile\n"; + +main(argc, argv) +int argc; +char *argv[]; +{ + extern int optind; + extern char *optarg; + int c; + FILE *f; + void dumpdescfile(), desceofsoexit(), seteoffunction(); + char *strcpy(); + + WhoAmI = argv[0]; + while ((c = getopt(argc, argv, "")) != EOF) + switch (c) { + case '?': +badusage: fprintf(stderr, Usage, WhoAmI); + exit(FAIL); + } + if (optind != argc - 1) + goto badusage; + if (!(f = fopen(argv[optind], "r"))) { + perror(argv[optind]); + exit(FAIL); + } + seteoffunction(desceofsoexit); + (void)strcpy(EOFName, argv[optind]); + dumpdescfile(f); + (void)fclose(f); + exit(SUCCEED); +} + +/* Symbolically dumps a DESC.out file. The parameter should be an open + * DESC.out file. + */ +void dumpdescfile(f) +FILE *f; +{ + unsigned char spacewidth, widthindex; + struct dev devheader; + struct font fontheader; + int count, c; + short size, index; + long funnycharoffset; /* Static file offset - Before */ + /* funnycharindextable. */ + long fontstructoffset; /* Floating offset - Beginning of each */ + /* font structure. */ + + rewind(f); + (void)cfread((char *)&devheader, sizeof(struct dev), 1, f); + printf("filesize: (%d+%d)=%d\n", sizeof(struct dev), devheader.filesize, + sizeof(struct dev) + devheader.filesize); + printf("res: %d\tmotion (hor,ver): (%d,%d)\n", devheader.res, + devheader.hor, devheader.vert); + printf("unitwidth: %d\tsizescale: %d\n", devheader.unitwidth, + devheader.sizescale); + printf("nfonts: %d\tnsizes: %d\n", devheader.nfonts, devheader.nsizes); + printf("paper (width,length): (%d,%d)\n", devheader.paperwidth, + devheader.paperlength); + /* Read the sizes table */ + printf("point sizes available:\n"); + (void)cfread((char *)&size, sizeof(short), 1, f); + for (count = 0; size; count++) { + if ((count + 1) % 20 == 0) + putchar('\n'); + printf("%d, ", size); + (void)cfread((char *)&size, sizeof(short), 1, f); + } + if (count > 0) + putchar('\n'); + /* Read the funnycharstrings */ + printf("special character names:\n"); + funnycharoffset = ftell(f); + for (count = 0; count < devheader.nchtab; count++) { + if ((count + 1) % 20 == 0) + putchar('\n'); + (void)fseek(f, funnycharoffset + count * sizeof(short), 0); + (void)cfread((char *)&index, sizeof(short), 1, f); + (void)fseek(f, funnycharoffset + devheader.nchtab * sizeof(short) + + index, 0); + while ((c = cgetc(f)) != '\0') + putchar(c); + putchar(','); + } + if (count > 0) + putchar('\n'); + (void)fseek(f, funnycharoffset + devheader.nchtab * sizeof(short) + + devheader.lchname, 0); + /* Read each individual font information */ + fontstructoffset = ftell(f); + while (fread((char *)&fontheader, sizeof(struct font), 1, f) == 1) { + printf("\n%s font %s (internal %s)\n", + fontheader.specfont == 1 ? "Special" : "Regular", + fontheader.namefont, fontheader.intname); + if (fontheader.ligfont > 0) { + printf("ligatures: "); + if (fontheader.ligfont & LFI) + printf("fi, "); + if (fontheader.ligfont & LFL) + printf("fl, "); + if (fontheader.ligfont & LFF) + printf("ff, "); + if (fontheader.ligfont & LFFI) + printf("ffi, "); + if (fontheader.ligfont & LFFL) + printf("ffl, "); + printf("\n"); + } + spacewidth = cgetc(f); + if (spacewidth > (unsigned)0) + printf("spacewidth: %u\n", spacewidth); + for (count = 0; count < 96 + devheader.nchtab; count++) { + /* Seek to fontindextable */ + (void)fseek(f, fontstructoffset + sizeof(struct font) + 3 * + fontheader.nwfont + count, 0); + widthindex = cgetc(f); + if (widthindex == 0) + continue; + if (count < 96) + if (count + 32 == 0177) /* Delete */ + printf("0177\t"); + else + printf("%c\t", count + 32); + else { + /* Print out special character sequence. */ + (void)fseek(f, funnycharoffset + (count - 96) * sizeof(short), + 0); + (void)cfread((char *)&index, sizeof(short), 1, f); + (void)fseek(f, funnycharoffset + devheader.nchtab * + sizeof(short) + index, 0); + while ((c = cgetc(f)) != '\0') + putchar(c); + putchar('\t'); + } + /* Print out width, kerning and code info */ + (void)fseek(f, fontstructoffset + sizeof(struct font) + widthindex, + 0); + printf("width %d\t", cgetc(f)); + (void)fseek(f, fontstructoffset + sizeof(struct font) + + fontheader.nwfont + widthindex, 0); + printf("kerning %d\t", cgetc(f)); + (void)fseek(f, fontstructoffset + sizeof(struct font) + + fontheader.nwfont * 2 + widthindex, 0); + printf("code %d\n", cgetc(f)); + } + /* Go to next font structure */ + (void)fseek(f, fontstructoffset + sizeof(struct font) + 3 * + fontheader.nwfont + 96 + devheader.nchtab, 0); + fontstructoffset = ftell(f); + } +} + +void desceofsoexit() +{ + fprintf(stderr, "%s: unexpected eof in DESC.out file %s\n", WhoAmI, + EOFName); + exit(FAIL); +} diff --git a/dviware/quicspool/src/dvi.h b/dviware/quicspool/src/dvi.h new file mode 100644 index 0000000000..899c6db066 --- /dev/null +++ b/dviware/quicspool/src/dvi.h @@ -0,0 +1,72 @@ +/* $Header: dvi.h,v 1.1 88/01/15 13:03:49 simpson Rel $ */ +/* +$Log: dvi.h,v $ + * Revision 1.1 88/01/15 13:03:49 simpson + * initial release + * + * Revision 0.1 87/12/11 18:30:51 simpson + * beta test + * +*/ +#define SETCHAR0 0 +#define SET1 128 +#define SET2 129 +#define SET3 130 +#define SET4 131 +#define SETRULE 132 +#define PUT1 133 +#define PUT2 134 +#define PUT3 135 +#define PUT4 136 +#define PUTRULE 137 +#define NOP 138 +#define BOP 139 +#define EOP 140 +#define PUSH 141 +#define POP 142 +#define RIGHT1 143 +#define RIGHT2 144 +#define RIGHT3 145 +#define RIGHT4 146 +#define W0 147 +#define W1 148 +#define W2 149 +#define W3 150 +#define W4 151 +#define X0 152 +#define X1 153 +#define X2 154 +#define X3 155 +#define X4 156 +#define DOWN1 157 +#define DOWN2 158 +#define DOWN3 159 +#define DOWN4 160 +#define Y0 161 +#define Y1 162 +#define Y2 163 +#define Y3 164 +#define Y4 165 +#define Z0 166 +#define Z1 167 +#define Z2 168 +#define Z3 169 +#define Z4 170 +#define FNTNUM0 171 +#define FNT1 235 +#define FNT2 236 +#define FNT3 237 +#define FNT4 238 +#define XXX1 239 +#define XXX2 240 +#define XXX3 241 +#define XXX4 242 +#define FNTDEF1 243 +#define FNTDEF2 244 +#define FNTDEF3 245 +#define FNTDEF4 246 +#define PRE 247 +#define POST 248 +#define POSTPOST 249 + +#define TRAILER 223 /* Trailing bytes at end of file */ diff --git a/dviware/quicspool/src/eqnchar b/dviware/quicspool/src/eqnchar new file mode 100644 index 0000000000..2e401c34ae --- /dev/null +++ b/dviware/quicspool/src/eqnchar @@ -0,0 +1,104 @@ +.\" $Header: eqnchar,v 1.1 88/01/15 13:03:55 simpson Rel $ +.\" $Log: eqnchar,v $ +.\" Revision 1.1 88/01/15 13:03:55 simpson +.\" initial release +.\" +.\" Revision 0.1 87/12/11 18:30:52 simpson +.\" beta test +.\" +.EQ +tdefine ciplus % "\o'\(pl\(ci'" % +ndefine ciplus % O+ % +tdefine citimes % "\o'\(mu\(ci'" % +ndefine citimes % Ox % +tdefine =wig % "\(eq\h'-\w'\(eq'u-\w'\s-1\(ap'u/2u'\v'-.4m'\s-1\z\(ap\(ap\s+1\v'.4m'\h'\w'\(eq'u-\w'\s-1\(ap'u/2u'" % +ndefine =wig % ="~" % +tdefine bigstar % "\o'\(pl\(mu'" % +ndefine bigstar % X|- % +tdefine =dot % "\z\(eq\v'-.6m'\h'.2m'\s+2.\s-2\v'.6m'\h'.1m'" % +ndefine =dot % = dot % +tdefine orsign % "\s-2\v'-.15m'\z\e\e\h'-.15m'\z\(sl\(sl\v'.15m'\s+2" % +ndefine orsign % \e/ % +tdefine andsign % "\s-2\v'-.15m'\z\(sl\(sl\h'-.15m'\z\e\e\v'.15m'\s+2" % +ndefine andsign % /\e % +tdefine =del % "\v'.3m'\z\(eq\v'-.6m'\s-1\(*D\s+1\v'.3m'" % +ndefine =del % = to DELTA % +tdefine oppA % "\s-2\v'-.15m'\z\e\e\h'-.15m'\z\(sl\(sl\v'-.15m'\h'-.75m'\z-\z-\h'.2m'\z-\z-\v'.3m'\h'.4m'\s+2" % +ndefine oppA % V- % +tdefine oppE %"\s-3\v'.2m'\z\(em\v'-.5m'\z\(em\v'-.5m'\z\(em\v'.50m'\h'1m'\z\(br\z\(br\v'.25m'\s+3" % +ndefine oppE % E/ % +tdefine incl % "\s-1\z\(or\v'-.5m'\z\(em\v'1.05m'\z\(em\v'.2m'\(em\v'-.75m'\s+1" % +ndefine incl % C_ % +tdefine nomem % "\o'\(mo\(sl'" % +ndefine nomem % C-/ % +tdefine angstrom % "\fR\zA\v'-.15m'\(de\v'.15m'\fP\h'.2m'" % +ndefine angstrom % A to o % +tdefine star %{ roman "\v'.4m'\s+3*\s-3\v'-.4m'"}% +ndefine star % * % +tdefine || % \(or\(or % +tdefine <wig % "\z<\v'.5m'\(ap\v'-.5m'" % +ndefine <wig %{ < from "~" }% +tdefine >wig % "\z>\v'.5m'\(ap\v'-.5m'" % +ndefine >wig %{ > from "~" }% +tdefine langle % "\s-3\b'\(sl\e'\s0" % +ndefine langle %<% +tdefine rangle % "\s-3\b'\e\(sl'\s0" % +ndefine rangle %>% +tdefine hbar % "\zh\v'-.6m'\h'.05m'\(ru\v'.6m'" % +ndefine hbar % h\u-\d % +ndefine ppd % _| % +tdefine ppd % "\h'.25m'\v'-.2m'\s-2\z\(or\s+2\h'-.25m'\v'.2m'\(ru" % +tdefine <-> % "\o'\(<-\(->'" % +ndefine <-> % "<-->" % +tdefine <=> % { roman "\s-2\z<\h'.3m'\z=\h'.45m'=\h'-.56m'>\s+2" } % +ndefine <=> % "<=>" % +tdefine |< % "\o'<\(or'" % +ndefine |< % <| % +tdefine |> % "\o'>\(or'" % +ndefine |> % |> % +tdefine ang % "\v'-.15m'\z\s-2\(sl\s+2\v'.15m'\(ru" % +ndefine ang % /_ % +tdefine rang % "\h'-.05m'\v'-.2m'\s-2\z\(or\s+2\h'.05m'\v'.2m'\(ru" % +ndefine rang % L % +tdefine 3dot % "\v'-.8m'\z.\v'.5m'\z.\v'.5m'.\v'-.2m'" % +ndefine 3dot % .\u.\u.\d\d % +tdefine thf % ".\v'-.5m'.\v'.5m'." % +ndefine thf % ..\u.\d % +tdefine quarter % roman \(14 % +ndefine quarter % 1/4 % +tdefine 3quarter % roman \(34 % +ndefine 3quarter % 3/4 % +tdefine degree % { roman \(de } % +ndefine degree % nothing sup o % +tdefine square % roman \(sq % +ndefine square % [] % +tdefine circle % \(ci % +ndefine circle % O % +tdefine blot % "\fB\(sq\fP" % +ndefine blot % HIX % +tdefine bullet % roman \(bu % +ndefine bullet % oxe % +tdefine -wig % "\(~=" % +ndefine -wig % - to "~" % +tdefine wig % \(ap % +ndefine wig % "~" % +tdefine prop % \(pt % +ndefine prop % oc % +tdefine empty % \(es % +ndefine empty % O/ % +tdefine member % \(mo % +ndefine member % C- % +tdefine cup % \(cu % +ndefine cup % U % +tdefine scrL % "\v'-.2m'\z\fI)\fP\fR(\fP\v'.2m'" % +ndefine scrL % (/ % +tdefine ==> % "\z>\v'.6m'\(eq\v'-.6m'\h'.05m'" % +ndefine ==> % >\d=\u % +tdefine ==< % "\z<\v'.6m'\(eq\v'-.6m'\h'.05m'" % +ndefine ==< % <\d=\u % +define cap % \(ca % +define subset % \(sb % +define supset % \(sp % +define !subset % \(ib % +define !supset % \(ip % +.EN diff --git a/dviware/quicspool/src/fontinfo.h b/dviware/quicspool/src/fontinfo.h new file mode 100644 index 0000000000..151d4ff298 --- /dev/null +++ b/dviware/quicspool/src/fontinfo.h @@ -0,0 +1,44 @@ +/* $Header: fontinfo.h,v 1.1 88/01/15 13:03:58 simpson Rel $ */ +/* +$Log: fontinfo.h,v $ + * Revision 1.1 88/01/15 13:03:58 simpson + * initial release + * + * Revision 0.1 87/12/11 18:30:53 simpson + * beta test + * +*/ + +/* Information on a whole font */ +struct FontInfo { + int blocksize; /* Estimated blocks >= real blocks */ + int qmsheight; /* Height to give QMS printer */ + int qmsbaseline; /* Baseline height to give QMS printer */ + int numchars; /* Number of characters in font */ + /* The following are just as in the PK documentation */ + char comment[256]; + long ds; /* Design size in FIXes */ + long cs; /* Checksum */ + long hppp, vppp; /* Pixel sps per point */ + struct charinfo { + long tfm; /* Width of character in FIXes/designsize */ + long dx, dy; /* Escapements in pixels sps */ + long w, h; /* Width, height in pixels */ + long hoff, voff; /* horizontal, vertical offset in pixels */ + } chararray[256]; +}; + +/* Information on a single character in a font */ +struct CharInfo { + long cc; /* Character found */ + long tfm; /* Width of character in FIXes/designsize */ + enum {pshort, pexshort, plong} preambletype; + long dxordm, dy; /* Escapements */ + long w, h; /* Width and height of bitmap */ + long hoff, voff; /* Offsets */ + char *bitmap; /* Raster bitmap. If type 'X' orientation + * then it is (w+7)/8 bytes wide, h tall. + * If type 'Y' orientation then it is (h+7)/8 + * bytes wide, w tall. + */ +}; diff --git a/dviware/quicspool/src/fontnode.h b/dviware/quicspool/src/fontnode.h new file mode 100644 index 0000000000..ab026ec5d7 --- /dev/null +++ b/dviware/quicspool/src/fontnode.h @@ -0,0 +1,27 @@ +/* $Header: fontnode.h,v 1.1 88/01/15 13:04:00 simpson Rel $ */ +/* +$Log: fontnode.h,v $ + * Revision 1.1 88/01/15 13:04:00 simpson + * initial release + * + * Revision 0.1 87/12/11 18:30:54 simpson + * beta test + * +*/ +#include <local/standard.h> +/* The following are flag masks */ +#define PORT 1 /* Portrait mode */ +#define RAM 2 /* This is a ram font */ +#define LOADED 4 /* Font is currently loaded in memory */ +#define PRELOADED 8 /* Font was in ram memory on startup */ + +/* All fonts may have the following information stored about them, regardless + * of whether we are using troff, TeX, etc. + */ +struct FontNode { + Bits flags; + int blocksize; /* in printer */ + int qmsnumber; + char *localinfo; /* Info local to typesetting program */ + struct FontNode *next; /* Store fonts as singly linked list */ +}; diff --git a/dviware/quicspool/src/getc.c b/dviware/quicspool/src/getc.c new file mode 100644 index 0000000000..cf935e18bb --- /dev/null +++ b/dviware/quicspool/src/getc.c @@ -0,0 +1,172 @@ +#ifndef lint +static char *rcs = "$Header: getc.c,v 1.1 88/01/15 13:04:03 simpson Rel $"; +#endif +/* +$Log: getc.c,v $ + * Revision 1.1 88/01/15 13:04:03 simpson + * initial release + * + * Revision 0.1 87/12/11 18:30:55 simpson + * beta test + * +*/ + +/* Secure getc(3) routines. These routines provide a set of standard I/O + * functions for reading data from files. The routines are essentially + * identical to their standard I/O equivalents except that these routines + * check for EOF. If EOF is encountered, a function determined by the user is + * called. This is useful if you are reading from a file, such as a TeX DVI + * file or troff file, and you want to check to see if the file ends + * prematurely without putting checks in every time you call getc(), gets(), + * etc. When reading a DVI file for example, you know when a file should end + * by the context, so if it does end prematurely, you can call an error + * routine. The following functions are provided: + * + * void seteoffunction(f) + * void (*f)(); + * + * Sets the function to call if EOF is reached when reading with any of the + * routines. The function is assumed not to return although returning is + * allowed. + * + * int cgetc(f) + * FILE *f; + * + * Just like getc(3) but it checks for EOF. If EOF is encountered, the + * function set in seteoffunction() is called. (It is really more like + * fgetc(3) since it is not a macro). + * + * int cgetchar() + * + * Equivalent to cgetc(stdin). It's not a macro since we would need an + * include file. + * + * int cgetw(f) + * FILE *f; + * + * Just like getw(3) but is checks for EOF. If EOF is encountered, the + * function set in seteoffunction() is called. + * + * char *cgets(s) + * char *s; + * + * Just like gets(3) except it checks for EOF. This is a little lie. + * Actually it only calls the function set in seteoffunction if it + * encounters EOF on the first character read. The rationale behind this is + * that you probably want the last line of a file even if it doesn't end with + * a newline. + * + * char *cfgets(s, n, stream) + * char *s; + * int n; + * FILE *stream; + * + * Just like fgets(3) except it checks for EOF. Again, it only calls the + * eof function if the first character read returns EOF. + * + * int cfread(ptr, size, nitems, stream) + * char *ptr; + * int size; + * int nitems; + * FILE *stream; + * + * Just like fread(3) except it checks for EOF. The size read must be the + * size expected. + */ + +#include <stdio.h> +#include <local/standard.h> + +static void (*EOFFunction)(); + +void seteoffunction(f) +void (*f)(); +{ + EOFFunction = f; +} + +int cgetc(f) +FILE *f; +{ + int c; + + if ((c = getc(f)) == EOF) { + if (EOFFunction) + (*EOFFunction)(); + } + else + return c; + return EOF; /* Only if EOFFunction returns or is NULL */ +} + +int cgetchar() +{ + return cgetc(stdin); +} + +int cgetw(f) +FILE *f; +{ + int w; + + w = getw(f); + if (feof(f)) { + if (EOFFunction) + (*EOFFunction)(); + } else + return w; + return EOF; /* Only if EOFFunction returns or is NULL */ +} + +char *cgets(s) +char *s; +{ + int c; + char *p = s; + + for (c = getchar(); c != '\n' && c != EOF; c = getchar()) + *p++ = c; + if (c == EOF && p == s) { + if (EOFFunction) + (*EOFFunction)(); + } else { + *p = '\0'; + return s; + } + return NULL; /* Only if EOFFunction returns or is NULL */ +} + +char *cfgets(s, n, stream) +char *s; +int n; +FILE *stream; +{ + int c = '\0'; + char *p = s, *strcat(); + + while (p - s < n - 1 && (c = getc(stream)) != '\n' && c != EOF) + *p++ = c; + if (c == EOF && p == s) { + if (EOFFunction) + (*EOFFunction)(); + } + else { + *p = '\0'; + if (c == '\n') + (void)strcat(s, "\n"); + return s; + } + return NULL; /* Only if EOFFunction returns or is NULL */ +} + +int cfread(ptr, size, nitems, stream) +char *ptr; +int size; +int nitems; +FILE *stream; +{ + if (fread(ptr, size, nitems, stream) != nitems) + if (EOFFunction) + (*EOFFunction)(); + return nitems; +} diff --git a/dviware/quicspool/src/gf.c b/dviware/quicspool/src/gf.c new file mode 100644 index 0000000000..33ccb06eaf --- /dev/null +++ b/dviware/quicspool/src/gf.c @@ -0,0 +1,419 @@ +#ifndef lint +static char *rcs = "$Header: gf.c,v 1.1 88/01/15 13:04:05 simpson Rel $"; +#endif +/* +$Log: gf.c,v $ + * Revision 1.1 88/01/15 13:04:05 simpson + * initial release + * + * Revision 0.1 87/12/11 18:30:56 simpson + * beta test + * +*/ +#include <stdio.h> +#include <signal.h> +#include <math.h> +#include <local/standard.h> +#include <local/qms.h> +#include <local/profile.h> +#include "constants.h" +#include "fontnode.h" + +enum linetypes { dotted, solid, longdashed, shortdashed, dotdashed }; +char *Whoami; /* argv[0] */ +int X, Y; +int PortraitFont = 1204; +int LandscapeFont = 1217; +int curx, cury, lowx, lowy, highx, highy; +double scalefactor; +enum linetypes linetype = solid; +extern char *User; +extern char *Host; +extern Boolean Accounting; +extern int NumPages; +extern FILE *Accting; + +main(argc, argv) +int argc; +char *argv[]; +{ + extern int optind; + extern char *optarg; + PROFILE_VALUE *v, *getbindingvalue(); + struct sigvec SigStruct; + int c, callcleanup(); + int xi, yi, x0, y0, x1, y1, r; + char s[256]; + void sanestate(), openpl(), move(), line(), label(), erase(), + point(), cont(), space(), arc(), circle(), linemod(), + closepl(), getstring(); + void cleanup(); + + Whoami = argv[0]; + while ((c = getopt(argc, argv, "x:y:n:h:w:l:")) != EOF) + switch (c) { + case 'x': + X = atoi(optarg); + break; + case 'y': + Y = atoi(optarg); + break; + case 'l': + case 'w': + break; + case 'n': + User = optarg; + break; + case 'h': + Host = optarg; + break; + case '?': + exit(2); + } + if (optind < argc) { + Accounting = TRUE; + if (!(Accting = fopen(argv[optind], "a"))) { + fprintf(stderr,"%s: cannot open accounting file %s\r\n", Whoami, + argv[optind]); + Accounting = FALSE; + } + } + if (X > 2550) { + if ((v = getbindingvalue("landscapefont")) && v->class == + PROFILE_INTEGER) + LandscapeFont = v->value.i; + } else if ((v = getbindingvalue("portraitfont")) && v->class == + PROFILE_INTEGER) + PortraitFont = v->value.i; + SigStruct.sv_handler = callcleanup; + SigStruct.sv_mask = 0; + SigStruct.sv_onstack = 0; + (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL); + openpl(); + while ((c = getchar()) != EOF) + switch (c) { + case 'm': + xi = getsi(stdin); + yi = getsi(stdin); + move(xi,yi); + break; + case 'l': + x0 = getsi(stdin); + y0 = getsi(stdin); + x1 = getsi(stdin); + y1 = getsi(stdin); + line(x0,y0,x1,y1); + break; + case 't': + getstring(s,stdin); + label(s); + break; + case 'e': + erase(); + break; + case 'p': + xi = getsi(stdin); + yi = getsi(stdin); + point(xi,yi); + break; + case 'n': + xi = getsi(stdin); + yi = getsi(stdin); + cont(xi,yi); + break; + case 's': + x0 = getsi(stdin); + y0 = getsi(stdin); + x1 = getsi(stdin); + y1 = getsi(stdin); + space(x0,y0,x1,y1); + break; + case 'a': + xi = getsi(stdin); + yi = getsi(stdin); + x0 = getsi(stdin); + y0 = getsi(stdin); + x1 = getsi(stdin); + y1 = getsi(stdin); + arc(xi,yi,x0,y0,x1,y1); + break; + case 'c': + xi = getsi(stdin); + yi = getsi(stdin); + r = getsi(stdin); + circle(xi,yi,r); + break; + case 'f': + getstring(s,stdin); + linemod(s); + break; + } + (void)sigblock(SIGINT); + closepl(); + fputs(QUICON, stdout); + cleanup((struct FontNode *)NULL, SUCCEED); +} + +callcleanup() +{ + void cleanup(); + + closepl(); + fputs(QUICON, stdout); + cleanup((struct FontNode *)NULL, SUCCEED); +} + +void openpl() +{ + fputs(QUICON, stdout); + if (X > 2550) + fputs(LANDSCAPE, stdout); + else + fputs(PORTRAIT, stdout); + printf("%s00000", SYNTAX); + printf("%s00000%05d", INITMARGVERT, X > 2550 ? (int)(8.5 * 1000) : 11 * + 1000); + printf("%s00000%05d", INITMARGHORZ, X > 2550 ? 11 * 1000 : (int)(8.5 * + 1000)); + printf("%s%d%s", DEFFONT, X > 2550 ? LandscapeFont : PortraitFont, + ENDCMD); + fputs(FREEOFF, stdout); + fputs(VECTORON, stdout); +} + +void move(x, y) +int x, y; +{ + curx = x; + cury = y; +} + +void line(x1, y1, x2, y2) +int x1, y1, x2, y2; +{ + fputs(VECTORON, stdout); + fputs("^V", stdout); + switch (linetype) { + case dotted: + printf("2"); + break; + case shortdashed: + printf("4"); + break; + case longdashed: + printf("6"); + break; + case dotdashed: + printf("7"); + break; + default: + printf("0"); + break; + } /* end switch */ + printf("^U%05d:%05d", (int)((x1 - lowx) * scalefactor / 300.0 * 1000.0), + (int)(((X > 2550 ? 8.5 : 11) - ((y1 - lowy) * scalefactor / + 300.0)) * 1000.0)); + printf("^D%05d:%05d", (int)((x2 - lowx) * scalefactor / 300.0 * 1000.0), + (int)(((X > 2550 ? 8.5 : 11) - ((y2 - lowy) * scalefactor / + 300.0)) * 1000.0)); + fputs(VECTOROFF, stdout); + curx = x2, cury = y2; +} + +void label(s) +char *s; +{ + double scale; + char *ptr; + + /* Each character is assumed to be 54 units wide without scaling. + Since the QMS fonts are proportional make sure that they are typeset + in the right place. The minimum width can be 45 dots (a 'W' in + font 1204) so adjust "scale" in case scalefactor would make + the width smaller than this. + 54*x = 45 x = 45/54 = 0.833333 + */ + scale = scalefactor; + if (scale < 0.833333) + scale = 0.833333; + for (ptr = s; *ptr != '\0' && *ptr != '\n'; ptr++) { + printf("\r^IV%05d", (int)(((X > 2550 ? 8.5 : 11) - (cury - + lowy) * scalefactor / 300.0) * 1000.0)); + printf("%s-00170", JUSTIFYRELATIVE); + printf("^IH%05d", (int)((curx - lowx) * scalefactor / 300.0 * + 1000.0)); + if (ptr - s > 0) + printf("%s+%05d", TABRELATIVE, (int)(54 * (ptr - s) * scale / + 300.0 * 1000.0)); + (void)putchar(*ptr); + } +} + +void erase() +{ + NumPages++; + putchar('\r'); + fputs(FORMFEED, stdout); +} + +void point(x, y) +{ + printf("^IH%05d", (int)((((curx - lowx) * scalefactor - 5.0) / 300.0) + * 1000.0)); + printf("^IV%05d", (int)(((X > 2550 ? 8.5 : 11) - ((cury - lowy) + * scalefactor - 5.0) / 300.0) * 1000.0)); + printf("%s0003300033", LINE); + curx = x; + cury = y; +} + +void cont(x, y) +int x, y; +{ + fputs(VECTORON, stdout); + fputs("^V", stdout); + switch (linetype) { + case dotted: + printf("2"); + break; + case shortdashed: + printf("4"); + break; + case longdashed: + printf("6"); + break; + case dotdashed: + printf("7"); + break; + default: + printf("0"); + break; + } /* end switch */ + printf("^U%05d:%05d", (int)((curx - lowx) * scalefactor / 300.0 * + 1000.0), (int)(((X > 2550 ? 8.5 : 11) - ((cury - lowy) * + scalefactor / 300.0)) * 1000.0)); + printf("^D%05d:%05d", (int)((x - lowx) * scalefactor / 300.0 * + 1000.0), (int)(((X > 2550 ? 8.5 : 11.0) - ((y - lowy) * + scalefactor / 300.0)) * 1000.0)); + fputs(VECTOROFF, stdout); + curx = x, cury = y; +} + +void space(x0, y0, x1, y1) +int x0, y0, x1, y1; +{ + double xscale, yscale; + + lowx = x0; + highx = x1; + lowy = y0; + highy = y1; + /* Pick smallest scale factor (x or y) and use it. Don't scale different + * x and y directions or the image will become distorted. + */ + xscale = (double)X / (highx - lowx); + yscale = (double)Y / (highy - lowy); + if (xscale > yscale) + scalefactor = yscale > 1.0 ? 1.0 : yscale; + else + scalefactor = xscale > 1.0 ? 1.0 : xscale; +} + +void arc(x, y, x0, y0, x1, y1) +{ + double dx, dy, startangle, endangle; + + fputs(DECIMALARC, stdout); + printf("+%05d+%05d", (int)((x - lowx) * scalefactor / 300.0 * 1000.0), + (int)(((X > 2550 ? 8.5 : 11.0) - ((y - lowy) * scalefactor / 300.0)) * + 1000.0)); + printf("%05d", (int)(sqrt(pow((double)x0 - x, 2.0) + /* radius */ + pow((double)y0 - y, 2.0)) * scalefactor / 300.0 * 1000.0)); + dx = x0 - x; + dy = y0 - y; + if (dx == 0.0) + startangle = dy > 0.0 ? 90.0 : -90.0; + else + startangle = atan2(dy, dx) / PI * 180.0; + if (startangle < 0.0) + startangle += 360.0; + startangle = 1000.0 - (startangle / 360.0 * 1000.0); + if (startangle == 1000.0) /* QMS only takes 3 digits */ + startangle = 999.0; + dx = x1 - x; + dy = y1 - y; + if (dx == 0.0) + endangle = dy > 0.0 ? 90.0 : -90.0; + else + endangle = atan2(dy, dx) / PI * 180.0; + if (endangle < 0.0) + endangle += 360.0; + endangle = 1000.0 - (endangle / 360.0 * 1000.0); + if (endangle == 1000.0) + endangle = 999.0; + /* Since the QMS draws clockwise, reverse points */ + printf("%03d%03d", (int)endangle, (int)startangle); + fputs("04", stdout); + fputs(ENDCMD, stdout); +} + +void circle(x, y, r) +int x, y, r; +{ + arc(x, y, x + r, y, x - r, y); + arc(x, y, x - r, y, x + r, y); +} + +void linemod(s) +char *s; +{ + int stringlen; + char *index(); + + if (index(s, '\n')) + stringlen = s - index(s, '\n'); + else + stringlen = 100; + if (EQN(s, "dotted", stringlen)) + linetype = dotted; + else if (EQN(s, "dotdashed", stringlen)) + linetype = dotdashed; + else if (EQN(s, "longdashed", stringlen)) + linetype = longdashed; + else if (EQN(s, "shortdashed", stringlen)) + linetype = shortdashed; + else + linetype = solid; +} + +void closepl() +{ + NumPages++; + (void)putchar('\r'); + fputs(FORMFEED, stdout); + fputs(QUICOFF, stdout); +} + +/* Get an integer stored in 2 ascii bytes */ +int getsi(fin) +FILE *fin; +{ + short a, b; + + if ((b = getc(fin)) == EOF) + return(EOF); + if ((a = getc(fin)) == EOF) + return(EOF); + a <<= 8; + return a | b; +} + +void getstring(s, fin) +char *s; +FILE *fin; +{ + for (; *s = getc(fin); s++) + if (*s == '\n') + break; + *s = '\0'; +} diff --git a/dviware/quicspool/src/glpq b/dviware/quicspool/src/glpq new file mode 100644 index 0000000000..9d3c9638c0 --- /dev/null +++ b/dviware/quicspool/src/glpq @@ -0,0 +1,32 @@ +#! /bin/csh +# $Header: glpq,v 1.1 88/01/15 13:04:09 simpson Rel $ +# $Log: glpq,v $ +#Revision 1.1 88/01/15 13:04:09 simpson +#initial release +# +#Revision 0.1 87/12/11 18:30:57 simpson +#beta test +# +set printers=(sneezy dopey grumpy) +set lpqflags +while ($#argv > 0) + switch ($1) + # if the -P option or a job number is given, only use one printer + case -P*: + lpq $lpqflags $* + exit + case [0-9]*: + lpq $lpqflags $* + exit + default: + set lpqflags=($lpqflags $1) + shift + breaksw + endsw +end +foreach i ($printers) + echo ${i}: + lpq -P$i $lpqflags + echo ${i}l: + lpq -P${i}l $lpqflags +end diff --git a/dviware/quicspool/src/glpr b/dviware/quicspool/src/glpr new file mode 100644 index 0000000000..99a8718b0f --- /dev/null +++ b/dviware/quicspool/src/glpr @@ -0,0 +1,104 @@ +#! /bin/csh +# $Header: glpr,v 1.1 88/01/15 13:04:11 simpson Rel $ +# $Log: glpr,v $ +#Revision 1.1 88/01/15 13:04:11 simpson +#initial release +# +#Revision 0.2 87/12/21 12:29:52 simpson +#changed spelling of queuing +# +#Revision 0.1 87/12/11 18:30:58 simpson +#beta test +# +# The algorithm is as follows: +# If given -P flag, use that printer +# Decide which printer to use by (minutes after hr modulo # of printers) +# Assign states to printer +# If printer is idle, use it +# Look for idle printer +# If found +# use it +# Look for busy printer +# If found +# use it +# Look for stopped printer +# If found +# use it +# Else all printers are disabled +# Printers can be in 4 states: 1==disabled, 2==stopped, 3==busy, 4==idle +set printers=(sneezy dopey grumpy) +set landscape +set lprflags +while ($#argv > 0) + switch ($1) + case -P*: + lpr $lprflags $* + exit + case -L: + set landscape=l + shift + breaksw + default: + set lprflags=($lprflags $1) + shift + breaksw + endsw +end +@ index = `date|sed 's/.* [0-9][0-9]:\([0-9][0-9]\).*/\1/'` % $#printers + 1 +set i = 1 +set states=($printers) +while ($i <= $#printers) + /etc/lpc status $printers[$i]$landscape|fgrep 'queuing is disabled'>\ + /dev/null + if ($status == 0) then + set states[$i] = 1 + @ i++ + continue + endif + /etc/lpc status $printers[$i]$landscape|fgrep 'printing is disabled'>\ + /dev/null + if ($status == 0) then + set states[$i] = 2 + @ i++ + continue + endif + lpq -P$printers[$i]|fgrep 'no entries'>/dev/null + set portraitstatus=$status + lpq -P$printers[$i]l|fgrep 'no entries'>/dev/null + if ($portraitstatus == 0 & $status == 0) then + set states[$i] = 4 + else + set states[$i] = 3 + endif + @ i++ +end +if ($states[$index] == 4) then + lpr -P$printers[$index]$landscape $lprflags + exit +endif +set i = 1 +while ($i <= $#printers) + if ($states[$i] == 4) then + lpr -P$printers[$i]$landscape $lprflags + exit + endif + @ i++ +end +set i = 1 +while ($i <= $#printers) + if ($states[$i] == 3) then + lpr -P$printers[$i]$landscape $lprflags + exit + endif + @ i++ +end +set i = 1 +while ($i <= $#printers) + if ($states[$i] == 2) then + lpr -P$printers[$i]$landscape $lprflags + exit + endif + @ i++ +end +# If we get here, all printers are disabled! Try anything! +lpr -P$printers[$index]$landscape $lprflags diff --git a/dviware/quicspool/src/if.c b/dviware/quicspool/src/if.c new file mode 100644 index 0000000000..3353371ff7 --- /dev/null +++ b/dviware/quicspool/src/if.c @@ -0,0 +1,221 @@ +#ifndef lint +static char *rcs = "$Header: if.c,v 1.1 88/01/15 13:04:16 simpson Rel $"; +#endif +/* +$Log: if.c,v $ + * Revision 1.1 88/01/15 13:04:16 simpson + * initial release + * + * Revision 0.1 87/12/11 18:30:58 simpson + * beta test + * +*/ +/* "if" filter + * This doesn't filter the input at all if the -c option is given. If the + * -c option is not given, then it converts \n into \r\n if it is not in + * QUIC mode. It performs accounting if an accounting file is given. It + * makes educated guesses as to the number of pages printed. Here is the + * page count algorithm: + * if -c option given then { + * if input string equals "^," + * increment page count + * else if input character is formfeed and not free format + * increment page count + * } else + * if not in QUIC mode { + * if input character is \n and line count is greater than the + * length of the page + * increment page count + * } else + * if input string equals "^," + * increment page count + * else if input character is formfeed and not free format + * increment page count + */ +#include <stdio.h> +#include <signal.h> +#include <local/qms.h> +#include <local/standard.h> +#include <local/profile.h> +#include "fontnode.h" + +char *WhoAmI; /* argv[0] */ +char *Model; +Boolean EnteredQuic = FALSE; +Boolean QuicMode = FALSE; +Boolean FreeForm = FALSE; +Boolean Raw = FALSE; +int LineNum = 1; +int CharCount = 1; +int Length; +int Width; +int Indent = 0; +int PortraitFont = 1204; +int LandscapeFont = 1217; +struct sigvec SigStruct; +extern char *User; +extern char *Host; +extern Boolean Accounting; +extern int NumPages; +extern FILE *Accting; + +main(argc, argv) +int argc; +char *argv[]; +{ + extern int optind; + extern char *optarg; + PROFILE_VALUE *v, *getbindingvalue(); + int c, callcleanup(); + void sanestate(); + void cleanup(); + + WhoAmI = argv[0]; + while ((c = getopt(argc, argv, "cw:l:i:n:h:")) != EOF) + switch (c) { + case 'c': + Raw = TRUE; + break; + case 'l': + Length = atoi(optarg); + break; + case 'w': + Width = atoi(optarg); + break; + case 'i': + Indent = atoi(optarg); + break; + case 'n': + User = optarg; + break; + case 'h': + Host = optarg; + break; + case '?': /* This should not happen */ + exit(2); + } + if (optind < argc) { + Accounting = TRUE; + if (!(Accting = fopen(argv[optind], "a"))) { + fprintf(stderr, "%s: cannot open accounting file %s\n", WhoAmI, + argv[optind]); + Accounting = FALSE; + } + } + if (!(v = getbindingvalue("model")) || v->class != PROFILE_STRING && + v->class != PROFILE_OTHER) { + fprintf(stderr, + "%s: model binding missing or invalid in configuration file\n", + WhoAmI); + exit(2); + } + Model = v->value.s; + if (Width > 80) { + if ((v = getbindingvalue("landscapefont")) && v->class == + PROFILE_INTEGER) + LandscapeFont = v->value.i; + } else + if ((v = getbindingvalue("portraitfont")) && v->class == + PROFILE_INTEGER) + PortraitFont = v->value.i; + SigStruct.sv_handler = callcleanup; + SigStruct.sv_mask = 0; + SigStruct.sv_onstack = 0; + (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL); + fputs(QUICON, stdout); + fputs(Width > 80 ? LANDSCAPE : PORTRAIT, stdout); + printf("%s00000", SYNTAX); + if (Raw) { + printf("%s00000%05d", INITMARGVERT, Width > 80 ? (int)(8.5 * 1000) : + 11 * 1000); + printf("%s00000%05d", INITMARGHORZ, Width > 80 ? 11 * 1000 : (int)(8.5 + * 1000)); + } else { + /* Different print engines can print in different parts of the page. + * For example, the Canon engine (QMS 800) cannot print in the top + * 1/4 inch of the page. The QMS 1500 uses a Ricoh engine. The + * 1200 and 2400 use a Xerox engine. We have to account for each + * by having different spacing. + */ + if (EQ(Model, "QMS800")) + if (Width > 80) { + printf("%s%05d%05d", INITMARGVERT, (int)(.4 * 1000), + (int)(8.5 * 1000)); + printf("%s%05d%05d", INITMARGHORZ, (int)(.325 * 1000), + 11 * 1000); + printf("%s%04d", LINESPACING, (int)(8.2 * 100)); + } else { + printf("%s%05d%05d", INITMARGVERT, (int)(.3 * 1000), + 11 * 1000); + printf("%s%05d%05d", INITMARGHORZ, (int)(.325 * 1000), + (int)(8.5 * 1000)); + printf("%s%04d", LINESPACING, (int)(6.1 * 100)); + } + else if (EQ(Model, "QMS1500")) + if (Width > 80) { + printf("%s%05d%05d", INITMARGVERT, (int)(.1 * 1000), + (int)(8.2 * 1000)); + printf("%s%05d%05d", INITMARGHORZ, (int)(.325 * 1000), + 11 * 1000); + printf("%s%04d", LINESPACING, (int)(8.2 * 100)); + } else { + printf("%s%05d%05d", INITMARGVERT, (int)(.1 * 1000), + (int)(10.85 * 1000)); + printf("%s%05d%05d", INITMARGHORZ, (int)(.325 * 1000), + (int)(8.5 * 1000)); + printf("%s%04d", LINESPACING, (int)(6.1 * 100)); + } + else /* Models 1200 and 2400 */ + if (Width > 80) { + printf("%s%05d%05d", INITMARGVERT, (int)(.32 * 1000), + (int)(8.5 * 1000)); + printf("%s%05d%05d", INITMARGHORZ, (int)(.325 * 1000), + 11 * 1000); + printf("%s%04d", LINESPACING, (int)(7.95 * 100)); + } else { + printf("%s%05d%05d", INITMARGVERT, (int)(.22 * 1000), + 11 * 1000); + printf("%s%05d%05d", INITMARGHORZ, (int)(.325 * 1000), + (int)(8.5 * 1000)); + printf("%s%04d", LINESPACING, (int)(6.02 * 100)); + } + if (Width > 80) { + if ((v = getbindingvalue("landscapepitch")) && (v->class == + PROFILE_INTEGER || v->class == PROFILE_FLOAT)) + if (v->class == PROFILE_INTEGER) + printf("%s%04d", CHARSPACING, v->value.i * 100); + else + printf("%s%04d", CHARSPACING, (int)(v->value.f * 100)); + } else + if ((v = getbindingvalue("portraitpitch")) && (v->class == + PROFILE_INTEGER || v->class == PROFILE_FLOAT)) + if (v->class == PROFILE_INTEGER) + printf("%s%04d", CHARSPACING, v->value.i * 100); + else + printf("%s%04d", CHARSPACING, (int)(v->value.f * 100)); + } + printf("%s%d%s", DEFFONT, Width > 80 ? LandscapeFont : PortraitFont, + ENDCMD); + fputs(FREEOFF, stdout); + fputs(QUICOFF, stdout); + while (yylex()) + ; + (void)sigblock(SIGINT); + if (Raw || EnteredQuic || LineNum != 1 || CharCount != 1) { + (void)putchar('\f'); + NumPages++; + } + fputs(QUICON, stdout); + cleanup((struct FontNode *)NULL, SUCCEED); +} + +int callcleanup() +{ + void cleanup(); + + fputs(QUICON, stdout); + fputs(FORMFEED, stdout), NumPages++; + cleanup((struct FontNode *)NULL, SUCCEED); +} + +#include "quic.c" diff --git a/dviware/quicspool/src/io.c b/dviware/quicspool/src/io.c new file mode 100644 index 0000000000..b1043cda50 --- /dev/null +++ b/dviware/quicspool/src/io.c @@ -0,0 +1,104 @@ +#ifndef lint +static char *rcs = "$Header: io.c,v 1.1 88/01/15 13:04:20 simpson Rel $"; +#endif +/* +$Log: io.c,v $ + * Revision 1.1 88/01/15 13:04:20 simpson + * initial release + * + * Revision 0.1 87/12/11 18:30:59 simpson + * beta test + * +*/ +/* General I/O routines */ + +#include <stdio.h> +#include <local/standard.h> +#include <ctype.h> + +/* Reads n bytes from file f into an unsigned long. The cgetc() routine is used + * so an appropriate error routine will need to be selected. */ +unsigned long uinteger(f, bytes) +FILE *f; +int bytes; +{ + int i; + long n = 0; + + for (i = 0; i < bytes; i++) + n = n << 8 | cgetc(f); + return n; +} + +/* Reads n bytes from file f into a long. The cgetc() routine is used so + * an appropriate error routine will need to be selected. */ +long integer(f, bytes) +FILE *f; +int bytes; +{ + int i; + long n = 0; + + for (i = 0; i < bytes; i++) { + n = n << 8 | cgetc(f); + if (i == 0 && n & 0x80) + n = n | ~0x7f; + } + return n; +} + +/* Gets the next character from the input that is not a space character. + * It calls cgetc() on EOF so the EOF function should be set appropriately. + */ +int getnonblank(f) +FILE *f; +{ + int c; + + while (isspace(c = cgetc(f))) + ; + return c; +} + +/* Gets the next integer from the input and returns its value. It calls + * cgetc() on EOF so the EOF function should be set appropriately. + */ +int getinteger(f) +FILE *f; +{ + int c, i = 0; + Boolean negative = FALSE; + + while (isspace(c = cgetc(f))) + ; + if (c == '-') { + negative = TRUE; + c = cgetc(f); + } + while ('0' <= c && c <= '9') { + i = i * 10 + c - '0'; + c = cgetc(f); + } + (void)ungetc(c, f); + if (negative) + i = -i; + return i; +} + +/* Reads the next blank delineated string from the file. It calls cgetc() + * so an EOF function should be set appropriately. The return value is static + * and is overwritten with each call. + */ +char *getstring(f) +FILE *f; +{ + static char buf[81]; + int c; + + c = getnonblank(f); + buf[0] = c, buf[1] = '\0'; + while (!isspace(c = cgetc(f))) + buf[strlen(buf)+1] = '\0', buf[strlen(buf)] = c; + (void)ungetc(c, f); + return buf; +} diff --git a/dviware/quicspool/src/list.c b/dviware/quicspool/src/list.c new file mode 100644 index 0000000000..f71598f48c --- /dev/null +++ b/dviware/quicspool/src/list.c @@ -0,0 +1,101 @@ +#ifndef lint +static char *rcs = "$Header: list.c,v 1.1 88/01/15 13:04:23 simpson Rel $"; +#endif +/* +$Log: list.c,v $ + * Revision 1.1 88/01/15 13:04:23 simpson + * initial release + * + * Revision 0.1 87/12/11 18:31:00 simpson + * beta test + * +*/ + +/* Routines for processing and returning information on font lists */ + +#include <stdio.h> +#include <local/qms.h> +#include "fontnode.h" + + +/* Returns a pointer to a font on the font list; NULL if not found */ +struct FontNode *getfontnode(head, fontnumber, orientation) +struct FontNode *head; +int fontnumber; +int orientation; +{ + struct FontNode *p; + + for (p = head; p; p = p->next) + if (p->qmsnumber == fontnumber && (p->flags & PORT ? 'P' : 'L') == + orientation) + return p; + return NULL; +} + +/* Puts the node passed as an argument on the end of the list. Fonts are + * deleted from the beginning of the list when making room in font memory + * so put the current font on the end of the list. + */ +void endoflist(head, thenode) +struct FontNode **head; +struct FontNode *thenode; +{ + struct FontNode *prev = NULL, *p; + + if (!head || !thenode) + return; + /* First delete it from the FontList */ + for (p = *head; p; prev = p, p = p->next) + if (p == thenode) + if (p == *head) + *head = (*head)->next; + else + prev->next = p->next; + thenode->next = NULL; + /* Tack it on the end */ + if (!*head) + *head = thenode; + else { + for (p = *head; p->next; p = p->next) + ; + p->next = thenode; + } +} + +/* Takes a list of fonts that are already loaded in the printer (i.e., the + * two lists returned by qmsfnt()) and returns a single list of FontNode's. + * We manipulate singly linked lists of FontNode's in each driver, not the + * lists returned by qmsfnt(). + */ +struct FontNode *createfontlist(fntinfo) +struct qmsfnt *fntinfo; +{ + struct fontnode *p; + struct FontNode *list = NULL, *new; + char *malloc(); + + if (!fntinfo) + return NULL; + for (p = fntinfo->rom; p; p = p->next) { + bzero((char *)(new = (struct FontNode *)malloc( + (unsigned)sizeof(struct FontNode))), sizeof(struct FontNode)); + new->next = list, list = new; /* Put on front of list */ + list->flags = LOADED | PRELOADED; + if (p->orientation == 'P') + list->flags |= PORT; + list->qmsnumber = p->number; + list->blocksize = CEILING(p->bytes / 1024.0); + } + for (p = fntinfo->ram; p; p = p->next) { + bzero((char *)(new = (struct FontNode *)malloc( + (unsigned)sizeof(struct FontNode))), sizeof(struct FontNode)); + new->next = list, list = new; + list->flags = RAM | LOADED | PRELOADED; + if (p->orientation == 'P') + list->flags |= PORT; + list->qmsnumber = p->number; + list->blocksize = CEILING(p->bytes / 1024); + } + return list; +} diff --git a/dviware/quicspool/src/makefile b/dviware/quicspool/src/makefile new file mode 100644 index 0000000000..6a2bde4be0 --- /dev/null +++ b/dviware/quicspool/src/makefile @@ -0,0 +1,152 @@ +# $Header: Makefile,v 1.2 88/02/03 08:52:35 simpson Exp $ +# $Log: Makefile,v $ +#Revision 1.2 88/02/03 08:52:35 simpson +#added tpic support +# +#Revision 1.1 88/01/15 13:03:01 simpson +#initial release +# +#Revision 0.2 87/12/18 11:25:41 simpson +#added spline file +# +#Revision 0.1 87/12/11 18:30:37 simpson +#beta test +# +CFLAGS=-O +LDFLAGS=-s +FILTER=/usr/local/lib/lpr +OTROFFFONT=/usr/lib/font +DITROFFFONT=/usr/lib/font/devqms +WWTEXFONT=/usr/lib/tex/qmsfonts +WBTEXFONT=/usr/lib/tex/imagenfonts +BINARIES=/usr/local/bin +DOCILEUSER=games + +all: of if rf gf df nf tf pktoch tfm2difont tfm2ofont dumpdesc cati + +configure: + sed s:--PKDIR1--:$(WBTEXFONT): < df.c.backup | \ + sed s:--PKDIR2--:$(WWTEXFONT): > df.c + sed s:--FONTDIR--:$(DITROFFFONT): < tf.c.backup > tf.c + sed s:--FONTDIR--:$(DITROFFFONT): < nf.c.backup > nf.c + sed s:--USER--:$(DOCILEUSER): < constants.h.backup > constants.h + sed s:--OFONT--:$(OTROFFFONT): < qtroff.backup | \ + sed s:--FILTER--:$(FILTER): > qtroff + sed s:--DIFONT--:$(DITROFFFONT): < ditroff.backup > ditroff + +of: of.o profile.o misc.o string.o + $(CC) -o $@ $(LDFLAGS) of.o profile.o misc.o string.o \ + ../libtrw/libtrw.a ../libprofile/libprofile.a ../libglob/libglob.a \ + ../libqmsquery/libqmsquery.a -ll -ltermcap + +if: if.o profile.o qms.o cleanup.o + $(CC) -o $@ $(LDFLAGS) if.o profile.o qms.o cleanup.o \ + ../libtrw/libtrw.a ../libprofile/libprofile.a ../libglob/libglob.a \ + ../libqmsquery/libqmsquery.a -ll -ltermcap + +rf: rf.o profile.o qms.o cleanup.o + $(CC) -o $@ $(LDFLAGS) rf.o profile.o qms.o cleanup.o \ + ../libtrw/libtrw.a ../libqmsquery/libqmsquery.a \ + ../libprofile/libprofile.a ../libglob/libglob.a -ll -ltermcap + +gf: gf.o profile.o qms.o cleanup.o + $(CC) -o $@ $(LDFLAGS) gf.o profile.o qms.o cleanup.o \ + ../libtrw/libtrw.a ../libqmsquery/libqmsquery.a \ + ../libprofile/libprofile.a ../libglob/libglob.a -ll -ltermcap -lm + +df: df.o cleanup.o getc.o io.o list.o misc.o pk.o profile.o qms.o spline.o \ + stack.o string.o table.o + $(CC) -o $@ $(LDFLAGS) df.o cleanup.o getc.o io.o list.o misc.o \ + pk.o profile.o qms.o spline.o stack.o string.o table.o \ + ../libtrw/libtrw.a ../libqmsquery/libqmsquery.a -ll \ + ../libprofile/libprofile.a ../libglob/libglob.a -ltermcap -lm + +nf: nf.o cleanup.o getc.o io.o list.o misc.o pk.o profile.o qms.o spline.o \ + stack.o string.o table.o + $(CC) -o $@ $(LDFLAGS) nf.o cleanup.o getc.o io.o list.o misc.o pk.o \ + profile.o qms.o spline.o stack.o string.o table.o ../libtrw/libtrw.a \ + ../libqmsquery/libqmsquery.a ../libprofile/libprofile.a \ + ../libglob/libglob.a -ll -ltermcap -lm + +tf: tf.o cat.o cleanup.o getc.o io.o list.o misc.o pk.o profile.o qms.o \ + stack.o string.o table.o + $(CC) -o $@ $(LDFLAGS) tf.o cat.o cleanup.o getc.o io.o list.o misc.o \ + pk.o profile.o qms.o stack.o string.o table.o ../libtrw/libtrw.a \ + ../libqmsquery/libqmsquery.a ../libprofile/libprofile.a \ + ../libglob/libglob.a -ll -ltermcap + +pktoch: pktoch.o misc.o pk.o io.o getc.o string.o + $(CC) $(LDFLAGS) -o $@ pktoch.o misc.o pk.o io.o getc.o string.o \ + ../libtrw/libtrw.a -ltermcap + +tfm2difont: tfm2difont.o getc.o io.o + $(CC) $(LDFLAGS) -o $@ tfm2difont.o getc.o io.o ../libtrw/libtrw.a + +tfm2ofont: tfm2ofont.o cat.o getc.o io.o + $(CC) $(LDFLAGS) -o $@ tfm2ofont.o cat.o getc.o io.o ../libtrw/libtrw.a + +dumpdesc: dumpdesc.o getc.o io.o + $(CC) $(LDFLAGS) -o $@ dumpdesc.o getc.o io.o ../libtrw/libtrw.a + +cati: cati.o + $(CC) $(LDFLAGS) -o $@ cati.o + +install: + install -m 755 if $(FILTER) + install -m 755 of $(FILTER) + install -m 755 rf $(FILTER) + install -m 755 gf $(FILTER) + install -m 755 tf $(FILTER) + install -o root -g daemon -m 4750 nf $(FILTER) + install -o root -g daemon -m 4750 df $(FILTER) + install -c -m 644 mount.nr $(FILTER) + install -m 755 tfm2ofont $(BINARIES) + install -m 755 tfm2difont $(BINARIES) + install -m 755 dumpdesc $(BINARIES) + install -m 755 pktoch $(BINARIES) + install -m 755 cati $(BINARIES) + install -c -m 755 qtroff $(BINARIES) + install -c -m 755 ditroff $(BINARIES) + install -c -m 755 glpr $(BINARIES) + install -c -m 755 glpq $(BINARIES) + +clean: + -rm -f of if rf gf df nf tf pktoch tfm2difont tfm2ofont dumpdesc cati \ + *.o lex.yy.c y.tab.c quic.c xxx.c xxxlex.c \ + df.c tf.c nf.c constants.h qtroff ditroff + +lint: + lint of.c profile.c misc.c string.c + lint if.c profile.c qms.c cleanup.c + lint rf.c profile.c qms.c cleanup.c + lint gf.c profile.c qms.c cleanup.c + lint df.c cleanup.c getc.c io.c list.c misc.c pk.c profile.c qms.c \ + stack.c string.c table.c + lint nf.c cleanup.c getc.c io.c list.c misc.c pk.c profile.c qms.c \ + spline.c stack.c string.c table.c + lint tf.c cat.c cleanup.c getc.c io.c list.c misc.c pk.c profile.c \ + qms.c stack.c string.c table.c + lint pktoch.c misc.c pk.c io.c getc.c string.c + lint tfm2ofont.c cat.c getc.c io.c + lint tfm2difont.c io.c getc.c + lint dumpdesc.c io.c getc.c + lint cati.c + +if.o: fontnode.h quic.c +rf.o: fontnode.h +gf.c: constants.h fontnode.h +df.o: dvi.h constants.h fontinfo.h fontnode.h xxx.c +nf.o: constants.h dev.h fontinfo.h fontnode.h xxx.c +tf.o: constants.h fontinfo.h fontnode.h +pktoch.o: fontinfo.h +tfm2difont.o: constants.h dev.h +tfm2ofont.o: constants.h +dumpdesc.o: dev.h +cleanup.o: constants.h fontnode.h +list.o: fontnode.h +misc.o: constants.h +pk.o: constants.h fontinfo.h pk.h +qms.o: fontnode.h +quic.c: quic.l +xxx.c: xxxlex.c xxx.y +xxxlex.c: xxxlex.l diff --git a/dviware/quicspool/src/makefile.trw b/dviware/quicspool/src/makefile.trw new file mode 100644 index 0000000000..ac2648aa29 --- /dev/null +++ b/dviware/quicspool/src/makefile.trw @@ -0,0 +1,190 @@ +# $Header: Makefile.TRW,v 1.2 88/02/03 08:52:38 simpson Exp $ +# $Log: Makefile.TRW,v $ +# Revision 1.2 88/02/03 08:52:38 simpson +# added tpic support +# +# Revision 1.1 88/01/15 13:03:05 simpson +# initial release +# +# Revision 0.2 87/12/18 11:34:39 simpson +# added spline file for pic +# +# Revision 0.1 87/12/11 19:13:28 simpson +# beta test +# +CFLAGS=-O -I/usr/src/usr.lib/lpr -DTRW +LDFLAGS=-s +FILTER=/usr/local/lib/lpr +OTROFFFONT=/usr/lib/font +DITROFFFONT=/usr/lib/font/devqms +WWTEXFONT=/usr/lib/tex/qmsfonts +WBTEXFONT=/usr/lib/tex/imagenfonts +BINARIES=/usr/local/bin +DOCILEUSER=games + +all: of if rf gf df nf tf pktoch tfm2difont tfm2ofont dumpdesc cati lpr lpd \ + lpq pac + +configure: + sed s:--PKDIR1--:$(WBTEXFONT): < df.c.backup | \ + sed s:--PKDIR2--:$(WWTEXFONT): > df.c + sed s:--FONTDIR--:$(DITROFFFONT): < tf.c.backup > tf.c + sed s:--FONTDIR--:$(DITROFFFONT): < nf.c.backup > nf.c + sed s:--USER--:$(DOCILEUSER): < constants.h.backup > constants.h + sed s:--OFONT--:$(OTROFFFONT): < qtroff.backup | \ + sed s:--FILTER--:$(FILTER): > qtroff + sed s:--DIFONT--:$(DITROFFFONT): < ditroff.backup > ditroff + +of: of.o profile.o misc.o string.o + $(CC) -o $@ $(LDFLAGS) of.o profile.o misc.o string.o \ + ../libtrw/libtrw.a ../libprofile/libprofile.a ../libglob/libglob.a \ + ../libqmsquery/libqmsquery.a -ll -ltermcap + +if: if.o profile.o qms.o cleanup.o + $(CC) -o $@ $(LDFLAGS) if.o profile.o qms.o cleanup.o \ + ../libtrw/libtrw.a ../libprofile/libprofile.a ../libglob/libglob.a \ + ../libqmsquery/libqmsquery.a -ll -ltermcap + +rf: rf.o profile.o qms.o cleanup.o + $(CC) -o $@ $(LDFLAGS) rf.o profile.o qms.o cleanup.o \ + ../libtrw/libtrw.a ../libqmsquery/libqmsquery.a \ + ../libprofile/libprofile.a ../libglob/libglob.a -ll -ltermcap + +gf: gf.o profile.o qms.o cleanup.o + $(CC) -o $@ $(LDFLAGS) gf.o profile.o qms.o cleanup.o \ + ../libtrw/libtrw.a ../libqmsquery/libqmsquery.a \ + ../libprofile/libprofile.a ../libglob/libglob.a -ll -ltermcap -lm + +df: df.o cleanup.o getc.o io.o list.o misc.o pk.o profile.o qms.o spline.o \ + stack.o string.o table.o + $(CC) -o $@ $(LDFLAGS) df.o cleanup.o getc.o io.o list.o misc.o \ + pk.o profile.o qms.o spline.o stack.o string.o table.o \ + ../libtrw/libtrw.a ../libqmsquery/libqmsquery.a -ll \ + ../libprofile/libprofile.a ../libglob/libglob.a -ltermcap -lm + +nf: nf.o cleanup.o getc.o io.o list.o misc.o pk.o profile.o qms.o spline.o \ + stack.o string.o table.o + $(CC) -o $@ $(LDFLAGS) nf.o cleanup.o getc.o io.o list.o misc.o pk.o \ + profile.o qms.o spline.o stack.o string.o table.o ../libtrw/libtrw.a \ + ../libqmsquery/libqmsquery.a ../libprofile/libprofile.a \ + ../libglob/libglob.a -ll -ltermcap -lm + +tf: tf.o cat.o cleanup.o getc.o io.o list.o misc.o pk.o profile.o qms.o \ + stack.o string.o table.o + $(CC) -o $@ $(LDFLAGS) tf.o cat.o cleanup.o getc.o io.o list.o misc.o \ + pk.o profile.o qms.o stack.o string.o table.o ../libtrw/libtrw.a \ + ../libqmsquery/libqmsquery.a ../libprofile/libprofile.a \ + ../libglob/libglob.a -ll -ltermcap + +pktoch: pktoch.o misc.o pk.o io.o getc.o string.o + $(CC) $(LDFLAGS) -o $@ pktoch.o misc.o pk.o io.o getc.o string.o \ + ../libtrw/libtrw.a -ltermcap + +tfm2difont: tfm2difont.o getc.o io.o + $(CC) $(LDFLAGS) -o $@ tfm2difont.o getc.o io.o ../libtrw/libtrw.a + +tfm2ofont: tfm2ofont.o cat.o getc.o io.o + $(CC) $(LDFLAGS) -o $@ tfm2ofont.o cat.o getc.o io.o ../libtrw/libtrw.a + +dumpdesc: dumpdesc.o getc.o io.o + $(CC) $(LDFLAGS) -o $@ dumpdesc.o getc.o io.o ../libtrw/libtrw.a + +cati: cati.o + $(CC) $(LDFLAGS) -o $@ cati.o + +lpr: lpr.o startdaemon.o printcap.o + $(CC) -o $@ $(LDFLAGS) lpr.o startdaemon.o printcap.o -lledger + +lpd: lpd.o printjob.o recvjob.o displayq.o rmjob.o startdaemon.o lpdchar.o \ + common.o printcap.o + $(CC) -o $@ $(LDFLAGS) lpd.o printjob.o recvjob.o displayq.o rmjob.o \ + startdaemon.o lpdchar.o common.o printcap.o -lledger + +lpq: lpq.o displayq.o common.o printcap.o + $(CC) -o $@ $(LDFLAGS) lpq.o displayq.o common.o printcap.o -ltermcap + +pac: pac.o printcap.o + $(CC) -o $@ $(LDFLAGS) pac.o printcap.o -ltrw -lledger -lprofile \ + -lglob + +install: + install -m 755 if $(FILTER) + install -m 755 of $(FILTER) + install -m 755 rf $(FILTER) + install -m 755 gf $(FILTER) + install -m 755 tf $(FILTER) + install -o root -g daemon -m 4750 nf $(FILTER) + install -o root -g daemon -m 4750 df $(FILTER) + install -o root -g daemon -m 6711 lpr /usr/ucb/lpr + install -o root -g daemon -m 6711 lpd /usr/lib/lpd + install -o root -g daemon -m 6711 lpq /usr/ucb/lpq + install -m 755 pac /etc + install -c -m 644 mount.nr $(FILTER) + install -m 755 tfm2ofont $(BINARIES) + install -m 755 tfm2difont $(BINARIES) + install -m 755 dumpdesc $(BINARIES) + install -m 755 pktoch $(BINARIES) + install -m 755 cati $(BINARIES) + install -c -m 755 qtroff $(BINARIES) + install -c -m 755 ditroff $(BINARIES) + install -c -m 755 glpr $(BINARIES) + install -c -m 755 glpq $(BINARIES) + +clean: + -rm -f of if rf gf df nf tf pktoch tfm2difont tfm2ofont dumpdesc cati \ + lpr lpd lpq pac *.o lex.yy.c y.tab.c quic.c xxx.c xxxlex.c \ + df.c tf.c nf.c constants.h qtroff ditroff + +lint: + lint of.c profile.c misc.c string.c + lint if.c profile.c qms.c cleanup.c + lint rf.c profile.c qms.c cleanup.c + lint gf.c profile.c qms.c cleanup.c + lint df.c cleanup.c getc.c io.c list.c misc.c pk.c profile.c qms.c \ + stack.c string.c table.c + lint nf.c cleanup.c getc.c io.c list.c misc.c pk.c profile.c qms.c \ + spline.c stack.c string.c table.c + lint tf.c cat.c cleanup.c getc.c io.c list.c misc.c pk.c profile.c \ + qms.c stack.c string.c table.c + lint pktoch.c misc.c pk.c io.c getc.c string.c + lint tfm2ofont.c cat.c getc.c io.c + lint tfm2difont.c io.c getc.c + lint dumpdesc.c io.c getc.c + lint cati.c + +if.o: fontnode.h quic.c +rf.o: fontnode.h +gf.c: constants.h fontnode.h +df.o: dvi.h constants.h fontinfo.h fontnode.h xxx.c +nf.o: constants.h dev.h fontinfo.h fontnode.h xxx.c +tf.o: constants.h fontinfo.h fontnode.h +pktoch.o: fontinfo.h +tfm2difont.o: constants.h dev.h +tfm2ofont.o: constants.h +dumpdesc.o: dev.h +lpd.o lpr.o startdaemon.o printjob.o displayq.o rmjob.o recvjob.ocommon.o \ +pac.o: /usr/src/usr.lib/lpr/lp.h /usr/src/usr.lib/lpr/lp.local.h +cleanup.o: constants.h fontnode.h +list.o: fontnode.h +misc.o: constants.h +pk.o: constants.h fontinfo.h pk.h +qms.o: fontnode.h +quic.c: quic.l +startdaemon.o: /usr/src/usr.lib/lpr/startdaemon.c + $(CC) -c $(CFLAGS) /usr/src/usr.lib/lpr/startdaemon.c +printcap.o: /usr/src/usr.lib/lpr/printcap.c + $(CC) -c $(CFLAGS) /usr/src/usr.lib/lpr/printcap.c +lpd.o: /usr/src/usr.lib/lpr/lpd.c + $(CC) -c $(CFLAGS) /usr/src/usr.lib/lpr/lpd.c +lpq.o: /usr/src/usr.lib/lpr/lpq.c + $(CC) -c $(CFLAGS) /usr/src/usr.lib/lpr/lpq.c +recvjob.o: /usr/src/usr.lib/lpr/recvjob.c + $(CC) -c $(CFLAGS) /usr/src/usr.lib/lpr/recvjob.c +rmjob.o: /usr/src/usr.lib/lpr/rmjob.c + $(CC) -c $(CFLAGS) /usr/src/usr.lib/lpr/rmjob.c +lpdchar.o: /usr/src/usr.lib/lpr/lpdchar.c + $(CC) -c $(CFLAGS) /usr/src/usr.lib/lpr/lpdchar.c +common.o: /usr/src/usr.lib/lpr/common.c + $(CC) -c $(CFLAGS) /usr/src/usr.lib/lpr/common.c +xxx.c: xxxlex.c xxx.y +xxxlex.c: xxxlex.l diff --git a/dviware/quicspool/src/misc.c b/dviware/quicspool/src/misc.c new file mode 100644 index 0000000000..1a6e60ed51 --- /dev/null +++ b/dviware/quicspool/src/misc.c @@ -0,0 +1,183 @@ +#ifndef lint +static char *rcs = "$Header: misc.c,v 1.1 88/01/15 13:04:30 simpson Rel $"; +#endif +/* +$Log: misc.c,v $ + * Revision 1.1 88/01/15 13:04:30 simpson + * initial release + * + * Revision 0.1 87/12/11 18:31:03 simpson + * beta test + * +*/ + +/* Miscellaneous routines */ + +#include <stdio.h> +#include <pwd.h> +#include <local/standard.h> +#include <ctype.h> +#include "constants.h" + +/* Same as the tgetent of termcap(3x) but it works for the printcap + * database. Use the rest of the termcap(3x) routines after you use + * this one. + */ +int pgetent(bp, name) +char *bp; +char *name; +{ + void setenv(); + + setenv("TERMCAP", "/etc/printcap"); + return tgetent(bp, name); +} + +/* Changes the uid of the running process to that of `user'. If the `host' is + * not equal to the current hostname, then a docile uid is switched to. TRUE + * is returned if the person selected in the password file exists and the uid + * is switched, FALSE otherwise. + */ +Boolean setnewid(host, user) +char *host, *user; +{ + char username[51]; + char hostname[51]; + char *strcpy(); + struct passwd *passwd; + + (void)strcpy(username, user); + (void)gethostname(hostname, 51); + if (!EQ(hostname, host)) + (void)strcpy(username, DOCILEUSER); + if (!(passwd = getpwnam(username))) + return FALSE; + seteuid(passwd->pw_uid); + setegid(passwd->pw_gid); + return TRUE; +} + +/* Gets the value of an environment variable just like getenv(3) but + * instead it reads the value of the environment variable from the user's + * .profile, .login or .cshrc file depending on what shell they are using. + * This is useful for processes that are not forked by the user but still + * wish to know the value of a user's environment variable. The .cshrc + * file is searched before the .login file. The returned value is static + * and the result is written over after each call as in getenv(3). NULL is + * returned if the user does not exist, the file is not readable or the + * environment variable does not exist. The string searched for should + * begin with "<variable name>=" in .profile or "setenv <variable name> " + * in the .cshrc or .login file. Continuation lines are handled too. If + * the user name that is passed is NULL then the current effective user id + * will used. + */ +char *fgetenv(variable, user) +char *variable; +char *user; +{ + struct passwd *passwd; + static char envvariable[201]; + char s[201], line[201], *strcpy(), *strcat(); + FILE *f; + Boolean continueline; + Boolean bourne; + Boolean dotcshrc = TRUE; + + if (!user) { + if (!(passwd = getpwuid(geteuid()))) + return NULL; + } else + if (!(passwd = getpwnam(user))) + return NULL; + if (!passwd->pw_shell || strlen(passwd->pw_shell) == 0 || + passwd->pw_shell && (EQ(passwd->pw_shell, "/bin/sh") || + EQ(passwd->pw_shell, "/bin/ksh"))) { + (void)sprintf(s, "%s/.profile", passwd->pw_dir); + bourne = TRUE; + } else { + (void)sprintf(s, "%s/.cshrc", passwd->pw_dir); + bourne = FALSE; + } +onceagain: + continueline = FALSE; + if (!(f = fopen(s, "r"))) + if (bourne) + return NULL; + else + goto trynextfile; + while (fgets(line, 201, f)) { + if (line[strlen(line) - 1] == '\n') + line[strlen(line) - 1] = '\0'; + if (bourne) + (void)sprintf(s, "%s=", variable); + else + (void)sprintf(s, "setenv %s ", variable); + /* Delete trailing blanks */ + while (strlen(line) > 0 && isspace(line[strlen(line) - 1])) + line[strlen(line) - 1] = '\0'; + if (continueline) + /* Check for \ on end of line */ + if (line[strlen(line) - 1] == '\\') { + line[strlen(line) - 1] = '\0'; + continueline = TRUE; + (void)strcat(envvariable, line); + } else { + (void)strcat(envvariable, line); + (void)fclose(f); + return envvariable; + } + else if (EQN(line, s, strlen(s))) { + if (line[strlen(line) - 1] == '\\') { + line[strlen(line) - 1] = '\0'; + (void)strcpy(envvariable, &line[strlen(s)]); + continueline = TRUE; + } else { + continueline = FALSE; + (void)strcpy(envvariable, &line[strlen(s)]); + (void)fclose(f); + return envvariable; + } + } else + continue; + } + if (continueline) { + (void)fclose(f); + return envvariable; + } + (void)fclose(f); +trynextfile: + if (!bourne && dotcshrc) { + (void)sprintf(s, "%s/.login", passwd->pw_dir); + dotcshrc = FALSE; + goto onceagain; + } + return NULL; +} + +void printbitmap(drawer, acter_set, egral, erceptor) +FILE *drawer; +char *acter_set; +int egral; +int erceptor; +{ + unsigned char red_human_bodies; /* Heeeeere's Johnny... */ + int erpret; /* -- Jack Nicholson */ + short cakes = (egral + 7) / 8; + long john, silver; + + for (erpret = 0; erpret < erceptor; erpret++) { + for (john = 0; john < cakes; john++) + if (john < cakes - 1) + for (red_human_bodies = 0x80, silver = 0; silver < 8; + silver++, red_human_bodies >>= 1) + fprintf(drawer, "%c", *(acter_set + cakes * erpret + + john) & red_human_bodies ? '*' : '.'); + else + for (red_human_bodies = 0x80, silver = 0; silver < (egral + 7) + % 8 + 1; silver++, red_human_bodies >>= 1) + fprintf(drawer, "%c", *(acter_set + cakes * erpret + + john) & red_human_bodies ? '*' : '.'); + fprintf(drawer, "\n"); + } +} + diff --git a/dviware/quicspool/src/mount.nr b/dviware/quicspool/src/mount.nr new file mode 100644 index 0000000000..5c9e59f159 --- /dev/null +++ b/dviware/quicspool/src/mount.nr @@ -0,0 +1,13 @@ +.\" $Header: mount.nr,v 1.1 88/01/15 13:04:34 simpson Rel $ +.\" $Log: mount.nr,v $ +.\" Revision 1.1 88/01/15 13:04:34 simpson +.\" initial release +.\" +.\" Revision 0.1 87/12/11 18:31:04 simpson +.\" beta test +.\" +.\" Mount the fonts on the positions or the width tables are not read +.fp 1 R +.fp 2 I +.fp 3 B +.fp 4 S diff --git a/dviware/quicspool/src/nf.c_backup b/dviware/quicspool/src/nf.c_backup new file mode 100644 index 0000000000..544b2cf126 --- /dev/null +++ b/dviware/quicspool/src/nf.c_backup @@ -0,0 +1,1329 @@ +/* Ditroff driver */ +#ifndef lint +static char *rcs = "$Header: nf.c.backup,v 1.2 88/02/03 08:52:15 simpson Exp $"; +#endif +/* +$Log: nf.c.backup,v $ +Revision 1.2 88/02/03 08:52:15 simpson +added tpic support + +Revision 1.1 88/01/15 13:04:37 simpson +initial release + +Revision 0.3 88/01/06 08:46:06 simpson +corrected determination of charexists + +Revision 0.2 87/12/18 11:37:32 simpson +added spline and ellipse support + +Revision 0.1 87/12/11 18:31:04 simpson +beta test + +*/ +#include <stdio.h> +#include <signal.h> +#include <math.h> +#include <assert.h> +#include <ctype.h> +#include <sys/types.h> +#include <sys/dir.h> +#include <local/standard.h> +#include <local/qms.h> +#include <local/profile.h> +#include "fontnode.h" +#include "fontinfo.h" +#include "constants.h" +#include "dev.h" + +#define FONTDIR "--FONTDIR--" +#define DEVNAME "qms" /* Name given to -T option*/ +/* Cast for accessing LocalInfo */ +#define LI(p) ((struct LocalInfo *)p->localinfo) +#define UNITWIDTH 10 /* Same as in DESC file */ + +typedef struct { + double x, y; +} COORDINATE; + +struct FontState { + int pointsize; + int font; +}; + +struct Stack { + struct FontState fontstate; + int h, v; +}; + +struct LocalInfo { + char name[21]; /* Name of font */ + int pointsize; + int qmsheight; /* Height to give QMS printer */ + int qmsbaseline; /* Baseline height to give QMS printer */ + char pathname[81]; /* Full pathname in file system */ + Boolean charexists[256];/* True if there is such a character */ + short bitmapsize[2][256]; /* Width & height of each char bitmap */ + short widths[256]; /* True width of each char in pixels */ + long maptable[160]; /* Encoding of troff special sequences */ + short maptablesize; /* # of entries in map table */ +}; + +char EOFName[101]; /* Used by pkeofsocleanup & desceofsocleanup */ +char *Whoami; /* argv[0] */ +char *Model; /* Model of printer being used */ +char Orientation = 'P'; +char MountTable[51][21]; /* Max of 50 different fonts in table */ +char *Xxxstring; /* String found in extension commands */ +char *Pxxxstring; /* Pointer used by the lexical analyzer */ +char PKDir[101]; /* Directory PK fonts are in */ +int MaxBlocks; /* # of free blocks w/out ram or rom fonts */ +int CurRamBlocks; /* # of blocks used by ram fonts */ +int CurRomBlocks; /* # of blocks used by rom fonts */ +int DownLoadFNum; /* Number of font currently being downloaded */ +int Origin[2]; /* Origin of a postprocessor graph in pixels */ +FILE *ReadLine; /* Debugger port tty */ +struct sigvec SigStruct; +struct FontNode *FontList; /* Contains all fonts & their attributes */ +extern char *Host, *User; +extern FILE *Accting; +extern Boolean Accounting; +extern int NumPages; + +main(argc, argv) +int argc; +char *argv[]; +{ + Boolean found, loadnametable(), setnewid(); + extern int optind; + extern char *optarg; + int *intptr, *tempintptr; + int c; + int romlist[41]; /* List of rom font #s */ + int simplyexit(), callcleanup(); + void qmsfntfree(), cleanup(), seteoffunction(), process(), + troffeofsocleanup(), adjust(); + PROFILE_VALUE *v, *getbindingvalue(); + struct qmsram *raminfo; + struct qmsfnt *fntinfo; + struct fontnode *p; + struct FontNode *createfontlist(); +#ifdef DEBUG + char *malloc(), orien; + int i, fontno, size; + FILE *f; + struct fontnode *fn; +#endif + + Whoami = argv[0]; + while ((c = getopt(argc, argv, "x:y:n:h:w:l:i:")) != EOF) + switch (c) { + case 'x': + if (atoi(optarg) > 2550) + Orientation = 'L'; + break; + case 'h': + Host = optarg; + break; + case 'n': + User = optarg; + break; + case 'y': + case 'w': + case 'l': + case 'i': + break; + default: + exit(2); + } + SigStruct.sv_handler = simplyexit; + SigStruct.sv_mask = 0; + SigStruct.sv_onstack = 0; + (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL); + if (optind < argc) { + Accounting = TRUE; + if (!(Accting = fopen(argv[optind], "a"))) { + fprintf(stderr, "%s: cannot open accounting file %s\n", Whoami, + argv[optind]); + Accounting = FALSE; + } + } + if (!(v = getbindingvalue("model")) || v->class != PROFILE_STRING && + v->class != PROFILE_OTHER) { + fprintf(stderr, + "%s: model binding missing or invalid in configuration file\n", + Whoami); + exit(2); + } + Model = v->value.s; + fputs(QUICON, stdout); + printf("%s^Z%s%s", CLEAROVERLAY, CLEARAOVERLAY, ENDCMD); + fputs(QUICOFF, stdout); + (void)fflush(stdout); + if (!(v = getbindingvalue("readline")) || v->class != PROFILE_STRING && + v->class != PROFILE_OTHER) { + fprintf(stderr, + "%s: readline binding missing or invalid in configuration file\n", + Whoami); + exit(2); + } + if (!(ReadLine = fopen(v->value.s, "r"))) { + fprintf(stderr, "%s: could not open %s for reading\n", Whoami, + v->value.s); + exit(2); + } +#ifdef DEBUG + raminfo = (struct qmsram *)malloc((unsigned)sizeof(struct qmsram)); + raminfo->TR = 401; + raminfo->AR = 387; + raminfo->FR = 13; + raminfo->OR = 0; +#else + qmsopen(fileno(stdout), fileno(ReadLine)); + if (!(raminfo = qmsram())) { + fprintf(stderr, "%s: could not get printer ram info\n", Whoami); + exit(2); + } +#endif + MaxBlocks = raminfo->AR + raminfo->FR; + /* Save 5 block for filling with tpic */ + MaxBlocks -= 5; +#ifdef DEBUG + fntinfo = (struct qmsfnt *)malloc((unsigned)sizeof(struct qmsfnt)); + fntinfo->ram = fntinfo->rom = NULL; + for (i = 0; i < 13; i++) { + switch (i) { + case 0: + fontno = 521; + orien = 'L'; + break; + case 1: + fontno = 522; + orien = 'L'; + break; + case 2: + fontno = 523; + orien = 'L'; + break; + case 3: + fontno = 524; + orien = 'L'; + break; + case 4: + fontno = 1100; + orien = 'P'; + break; + case 5: + fontno = 1103; + orien = 'P'; + break; + case 6: + fontno = 1200; + orien = 'P'; + break; + case 7: + fontno = 1204; + orien = 'P'; + break; + case 8: + fontno = 1217; + orien = 'L'; + case 9: + fontno = 7009; + orien = 'P'; + break; + case 10: + fontno = 7010; + orien = 'P'; + break; + case 11: + fontno = 7036; + orien = 'P'; + break; + case 12: + fontno = 7037; + orien = 'P'; + break; + } + fn = (struct fontnode *)malloc((unsigned)sizeof(struct fontnode)); + fn->next = fntinfo->rom, fntinfo->rom = fn; + fn->orientation = orien; + fn->number = fontno; + fn->bytes = 1024; /* Rom fonts occupy one block */ + fn->version = '0'; + fn->class = '1'; + } + /* For testing, ramfonts contains the already loaded fonts. It should + * consist of lines containing two numbers and a letter, the first being + * the font number, the second being the font size, and the third letter + * is an orientation. The orientation should be the character immediately + * after the size of the font. + */ + if (f = fopen("ramfonts", "r")) { /* File is optional for testing */ + while (fscanf(f, "%d%d%c", &fontno, &size, &orien) == 3) + { + fn = (struct fontnode *)malloc((unsigned)sizeof(struct fontnode)); + fn->next = fntinfo->ram, fntinfo->ram = fn; + fn->orientation = orien; + fn->number = fontno; + fn->bytes = size; + fn->version = '0'; + fn->class = '1'; + raminfo->AR -= CEILING(size / 1024.0); + raminfo->FR += CEILING(size / 1024.0); + } + (void)fclose(f); + } +#else + if (!(fntinfo = qmsfnt())) { + fprintf(stderr, "%s: could not get printer font info\n", Whoami); + exit(2); + } +#endif + for (CurRomBlocks = 0, p = fntinfo->rom; p; p = p->next) + CurRomBlocks += CEILING(p->bytes / (double)1024); + CurRamBlocks = raminfo->FR - CurRomBlocks; + /* Make an array of rom font #s */ + for (p = fntinfo->rom, intptr = romlist; p; p = p->next) { + for (tempintptr = romlist, found = FALSE; tempintptr < intptr; + tempintptr++) + if (*tempintptr == p->number) + found = TRUE; + if (!found) + *intptr++ = p->number; + } + *intptr = 0; + if (EQ(Model, "QMS800")) + (void)sprintf(PKDir, "%s/wbfonts", FONTDIR); + else + (void)sprintf(PKDir, "%s/wwfonts", FONTDIR); + if (!loadnametable(PKDir, romlist, 10001)) { + fprintf(stderr, "%s: could not open font directory %s\n", Whoami, + PKDir); + exit(2); + } + FontList = createfontlist(fntinfo); + qmsfntfree(fntinfo); + if (!setnewid(Host, User)) { + fprintf(stderr, "%s: could not change user id to %s\n", Whoami, + User); + exit(2); /* This is fatal bud */ + } + SigStruct.sv_handler = callcleanup; + (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL); + fputs(QUICON, stdout); + if (Orientation == 'P') + fputs(PORTRAIT, stdout); + else + fputs(LANDSCAPE, stdout); + printf("%s%c%c", TEXTPROC, '0', '0'); + printf("%s00000%05d", INITMARGVERT, Orientation == 'P' ? 11 * 1000 : + (int)(8.5 * 1000)); + printf("%s00000%05d", INITMARGHORZ, Orientation == 'P' ? (int)(8.5 * 1000) + : 11 * 1000); + printf("%s0000", CHARSPACING); + fputs(FREEOFF, stdout); + seteoffunction(troffeofsocleanup); + process(); + cleanup(FontList, SUCCEED); +} + +/* Main routine that interprets the troff file */ +void process() +{ + int specialfont = 4; /* Loc of S font in mount table */ + int c, d, n; + int realhpxl = 0, realvpxl = 0, + virthpxl = 0, virtvpxl = 0; /*Virt & real cursor locs - pxls*/ + Boolean switchedtospecial = FALSE;/* T if we switch to Special font */ + Boolean firstpage = TRUE, fontselected = FALSE, download(), makeroom(); + char *malloc(), *getstring(), *push(), *pop(), *strcpy(), *s, + *findpkfont(), extension[1000], *cgets(), *extractinteger(); + void endoflist(), spline(); + double radius, anglestart, angleend, decimalanglestart, a, b, + decimalangleend, controlpoints[37][3], curvepoints[500][3]; + COORDINATE start, end, center, cur, new; + struct Stack *tempstack; + struct FontNode *fonttolist(); + struct FontNode *curnode = NULL; /* Current font ditroff has selected */ + struct FontNode *oldnode; /* 4 saving when trying special font */ + /* Current font ditroff has selected */ + struct FontState current; + /* For saving font when trying the special font */ + struct FontState oldcurrent; + + current.font = current.pointsize = 0; + bzero((char *)MountTable, sizeof(MountTable)); + while (TRUE) { /* A non-returning function is called to exit */ + switch (c = getnonblank(stdin)) { + case 's': + current.pointsize = getinteger(stdin); + curnode = fonttolist(MountTable[current.font], current.pointsize); + endoflist(&FontList, curnode); + fontselected = FALSE; + putchar('\r'); /* Ends the pass */ + printf("%s00000%s", TAB, ENDCMD); + printf("%s00000%s", JUSTIFYMARGIN, ENDCMD); + realhpxl = realvpxl = 0; + break; + case 'f': + current.font = getinteger(stdin); + curnode = fonttolist(MountTable[current.font], current.pointsize); + endoflist(&FontList, curnode); + fontselected = FALSE; + putchar('\r'); /* Ends the pass */ + printf("%s00000%s", TAB, ENDCMD); + printf("%s00000%s", JUSTIFYMARGIN, ENDCMD); + realhpxl = realvpxl = 0; + break; + case 'c': /* Character at current location */ + c = cgetchar(); + /* If we couldn't find the font, don't print anything since we + * don't know how to increment the real & virtual pixel locations. + */ + if (!curnode || !curnode->localinfo || !LI(curnode)->charexists[c]) + { + oldcurrent = current; + current.font = specialfont; + oldnode = curnode; + curnode = fonttolist(MountTable[current.font], + current.pointsize); + if (curnode && curnode->localinfo && + LI(curnode)->charexists[c]) { + endoflist(&FontList, curnode); + fontselected = FALSE; + putchar('\r'); + printf("%s00000%s", TAB, ENDCMD); + printf("%s00000%s", JUSTIFYMARGIN, ENDCMD); + realhpxl = realvpxl = 0; + switchedtospecial = TRUE; + } else { + current = oldcurrent; + curnode = oldnode; + continue; + } + } + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl); + if (!(curnode->flags & LOADED)) { + if (!makeroom(FontList, MaxBlocks, &CurRamBlocks, CurRomBlocks, + curnode->blocksize)) { + fprintf(stderr, + "%s: could not free %d blocks for font %s\n", Whoami, + curnode->blocksize, LI(curnode)->pathname); + goto trytocontinue1; + } + if (!download(curnode)) + goto trytocontinue1; + realhpxl = realvpxl = 0; + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl); + } + if (!fontselected) { + printf("%s%d%s", DEFFONT, curnode->qmsnumber, ENDCMD); + fontselected = TRUE; + } + /* For fonts with width but no bitmap, check the size of the + * raster. The QMS will not print (or download) a character with + * width and no bitmap so we must not print characters that are not + * in the font. If you do, you will get the lowest character in + * the font. + */ +trytocontinue1: + if (LI(curnode)->bitmapsize[0][c] != 0 && + LI(curnode)->bitmapsize[1][c] != 0) { + if (c == '^' || c <= 32 || c >= 127) + printf("%s%02X", SPECIAL, c); + else + (void)putchar(c); + realhpxl += LI(curnode)->widths[c]; + } + if (switchedtospecial) { /* Switch back */ + switchedtospecial = FALSE; + current = oldcurrent; + curnode = oldnode; + fontselected = FALSE; + } + break; + case 'C': + s = getstring(stdin); + if (!curnode || !curnode->localinfo || (c = + lookup(LI(curnode)->maptable, LI(curnode)->maptablesize, s)) == -1 + || !LI(curnode)->charexists[c = LI(curnode)->maptable[c] >> 24 & + 0xFF]) { + oldcurrent = current; + current.font = specialfont; + oldnode = curnode; + curnode = fonttolist(MountTable[current.font], + current.pointsize); + if (curnode && curnode->localinfo && (c = + lookup(LI(curnode)->maptable, LI(curnode)->maptablesize, s)) + != -1 && LI(curnode)->charexists[c = LI(curnode)->maptable[c] + >> 24 & 0xFF]) { + endoflist(&FontList, curnode); + fontselected = FALSE; + putchar('\r'); + printf("%s00000%s", TAB, ENDCMD); + printf("%s00000%s", JUSTIFYMARGIN, ENDCMD); + realhpxl = realvpxl = 0; + switchedtospecial = TRUE; + } else { + current = oldcurrent; + curnode = oldnode; + continue; + } + } + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl); + if (!(curnode->flags & LOADED)) { + if (!makeroom(FontList, MaxBlocks, &CurRamBlocks, CurRomBlocks, + curnode->blocksize)) { + fprintf(stderr, + "%s: could not free %d blocks for font %s\n", Whoami, + curnode->blocksize, LI(curnode)->pathname); + goto trytocontinue2; + } + if (!download(curnode)) + goto trytocontinue2; + realhpxl = realvpxl = 0; + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl); + } + if (!fontselected) { + printf("%s%d%s", DEFFONT, curnode->qmsnumber, ENDCMD); + fontselected = TRUE; + } +trytocontinue2: + if (LI(curnode)->bitmapsize[0][c] != 0 && + LI(curnode)->bitmapsize[1][c] != 0) { + if (c == '^' || c <= 32 || c >= 127) + printf("%s%02X", SPECIAL, c); + else + (void)putchar(c); + realhpxl += LI(curnode)->widths[c]; + } + if (switchedtospecial) { /* Switch back */ + switchedtospecial = FALSE; + current = oldcurrent; + curnode = oldnode; + fontselected = FALSE; + } + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + virthpxl += (c - '0') * 10 + (cgetchar() - '0'); + c = cgetchar(); + if (!curnode || !curnode->localinfo || !LI(curnode)->charexists[c]) + { + oldcurrent = current; + current.font = specialfont; + oldnode = curnode; + curnode = fonttolist(MountTable[current.font], + current.pointsize); + if (curnode && curnode->localinfo && + LI(curnode)->charexists[c]) { + endoflist(&FontList, curnode); + fontselected = FALSE; + putchar('\r'); + printf("%s00000%s", TAB, ENDCMD); + printf("%s00000%s", JUSTIFYMARGIN, ENDCMD); + realhpxl = realvpxl = 0; + switchedtospecial = TRUE; + } else { + current = oldcurrent; + curnode = oldnode; + continue; + } + } + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl); + if (!(curnode->flags & LOADED)) { + if (!makeroom(FontList, MaxBlocks, &CurRamBlocks, + CurRomBlocks, curnode->blocksize)) { + fprintf(stderr, + "%s: could not free %d blocks for font %s\n", Whoami, + curnode->blocksize, LI(curnode)->pathname); + goto trytocontinue3; + } + if (!download(curnode)) + goto trytocontinue3; + realhpxl = realvpxl = 0; + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl); + } + if (!fontselected) { + printf("%s%d%s", DEFFONT, curnode->qmsnumber, ENDCMD); + fontselected = TRUE; + } +trytocontinue3: + if (LI(curnode)->bitmapsize[0][c] != 0 && + LI(curnode)->bitmapsize[1][c] != 0) { + if (c == '^' || c <= 32 || c >= 127) + printf("%s%02X", SPECIAL, c); + else + (void)putchar(c); + realhpxl += LI(curnode)->widths[c]; + } + if (switchedtospecial) { /* Switch back */ + switchedtospecial = FALSE; + current = oldcurrent; + curnode = oldnode; + fontselected = FALSE; + } + break; + case 'p': /* Begin a new page */ + (void)getinteger(stdin); /* Ignore page number */ + realhpxl = realvpxl = virthpxl = virtvpxl = 0; + printf("%s%05d%s", TAB, 0, ENDCMD); + printf("%s%05d%s", JUSTIFYMARGIN, 0, ENDCMD); + if (!firstpage) + fputs(FORMFEED, stdout), NumPages++; + else + firstpage = FALSE; + break; + case 'w': /* Appears between words - ignore */ + break; + case 'H': /* Absolute horizontal */ + virthpxl = getinteger(stdin); + break; + case 'h': /* Relative horizontal */ + virthpxl += getinteger(stdin); + break; + case 'V': /* Absolute vertical */ + virtvpxl = getinteger(stdin); + break; + case 'v': /* Relative vertical */ + virtvpxl += getinteger(stdin); + break; + case 'n': /* At end of line */ + (void)getinteger(stdin); /* Amount of space before line */ + (void)getinteger(stdin); /* Amount of space after line */ + break; + case '{': /* Push stack */ + tempstack = (struct Stack *)malloc(sizeof(struct Stack)); + tempstack->fontstate.pointsize = current.pointsize; + tempstack->fontstate.font = current.font; + tempstack->h = virthpxl, tempstack->v = virtvpxl; + (void)push((char *)&tempstack); + break; + case '}': /* Pop stack */ + tempstack = (struct Stack *)pop(); + current.pointsize = tempstack->fontstate.pointsize; + current.font = tempstack->fontstate.font; + virthpxl = tempstack->h, virtvpxl = tempstack->v; + curnode = fonttolist(MountTable[current.font], current.pointsize); + endoflist(&FontList, curnode); + free((char *)tempstack); + fontselected = FALSE; + putchar('\r'); /* Ends the pass */ + printf("%s00000%s", TAB, ENDCMD); + printf("%s00000%s", JUSTIFYMARGIN, ENDCMD); + realhpxl = realvpxl = 0; + break; + case '#': /* Comment */ + while (cgetchar() != '\n') + ; + break; + case 'D': /* Graphics drawing commands */ + switch (c = cgetchar()) { + case 'l': /* Line */ + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl); + start.x = virthpxl, start.y = virtvpxl; + end.x = start.x + getinteger(stdin), end.y = start.y + + getinteger(stdin); + /* I don't know what this next character is. It is not + * documented. + */ + while ((c = cgetchar()) != '\n'); + ; + fputs(VECTORON, stdout); + printf("%s%05d:%05d", PENUP, + ROUND(virthpxl/(double)RESOLUTION*1000), + ROUND(virtvpxl/(double)RESOLUTION*1000)); + printf("%s03", PENWIDTH); + printf("%s%05d:%05d", PENDOWN, ROUND(end.x / RESOLUTION * + 1000), ROUND(end.y / RESOLUTION * 1000)); + fputs(VECTOROFF, stdout); + printf("%s00000%s00000%s\r", TAB, JUSTIFYMARGIN, ENDCMD); + virthpxl = ROUND(end.x), virtvpxl = ROUND(end.y); + realhpxl = realvpxl = 0; + break; + case 'c': /* Circle */ + d = getinteger(stdin); + printf("%s%c%05d%c%05d%05d%03d%03d%02d%s", ARC, + virthpxl+.5*d>=0.0?'+':'-', ROUND((virthpxl+.5*d)/RESOLUTION + *1000.0), + virtvpxl>=0?'+':'-', ROUND(virtvpxl/(double)RESOLUTION*1000.0), + ROUND(.5*d/RESOLUTION*1000.0), + 0,0,3,ENDCMD); + printf("%s00000%s00000%s", TAB, JUSTIFYMARGIN, ENDCMD); + realhpxl = realvpxl = 0; + virthpxl += d; + break; + case 'e': /* Ellipse */ + /* Ellipses satisfy the equation (x^2)/(a^2)+(y^2)/(b^2)=1 + * where 'a' is the length of the semimajor axis and 'b' is + * the length of the semiminor axis. We divide each quadrant + * into 200 line segments and connect the line segments. + */ + a = getinteger(stdin) / 2.0 / RESOLUTION, /* In inches */ + b = getinteger(stdin) / 2.0 / RESOLUTION; + center.x = virthpxl / (double)RESOLUTION + a, + center.y = virtvpxl / (double)RESOLUTION; + cur.x = a, cur.y = 0.0; /* cur and new are */ + fputs(VECTORON, stdout); /* relative to the origin */ + printf("%s03", PENWIDTH); + for (n = 1; n <= 200; n++, cur = new) { + new.x = a*cos((n/200.0)*(PI/2.0)), + new.y = b*sin((n/200.0)*(PI/2.0)); + /* First quadrant */ + printf("%s%05d:%05d", PENUP, + ROUND((center.x+cur.x)*1000.0), + ROUND((center.y+cur.y)*1000.0)); + printf("%s%05d:%05d", PENDOWN, + ROUND((center.x+new.x)*1000.0), + ROUND((center.y+new.y)*1000.0)); + /* Second quadrant */ + printf("%s%05d:%05d", PENUP, + ROUND((center.x-cur.x)*1000.0), + ROUND((center.y+cur.y)*1000.0)); + printf("%s%05d:%05d", PENDOWN, + ROUND((center.x-new.x)*1000.0), + ROUND((center.y+new.y)*1000.0)); + /* Third quadrant */ + printf("%s%05d:%05d", PENUP, + ROUND((center.x-cur.x)*1000.0), + ROUND((center.y-cur.y)*1000.0)); + printf("%s%05d:%05d", PENDOWN, + ROUND((center.x-new.x)*1000.0), + ROUND((center.y-new.y)*1000.0)); + /* Fourth quadrant */ + printf("%s%05d:%05d", PENUP, + ROUND((center.x+cur.x)*1000.0), + ROUND((center.y-cur.y)*1000.0)); + printf("%s%05d:%05d", PENDOWN, + ROUND((center.x+new.x)*1000.0), + ROUND((center.y-new.y)*1000.0)); + } + fputs(VECTOROFF, stdout); + printf("%s00000%s00000\r", TAB, JUSTIFYMARGIN, ENDCMD); + virthpxl += ROUND(2.0 * a * RESOLUTION); + realhpxl = realvpxl = 0; + break; + case 'a': /* Arc */ + start.x = virthpxl, start.y = virtvpxl; + center.x = virthpxl + getinteger(stdin), center.y = virtvpxl + + getinteger(stdin); + end.x = center.x + getinteger(stdin), end.y = center.y + + getinteger(stdin); + radius = sqrt(pow(start.x - center.x, 2.0) + pow(start.y - + center.y, 2.0)); + /* Ditroff uses reverse cartesian coordinate system */ + anglestart = atan2(start.x - center.x, center.y - start.y); + angleend = atan2(end.x - center.x, center.y - end.y); + anglestart -= PI / 2.0; + angleend -= PI / 2.0; + if (anglestart < 0) + anglestart += 2 * PI; + if (angleend < 0) + angleend += 2 * PI; + decimalanglestart = angleend / PI * 500.0; + decimalangleend = anglestart / PI * 500.0; + printf("%s%c%05d%c%05d%05d%03d%03d%02d%s", DECIMALARC, + center.x>0?'+':'-', ROUND(center.x/RESOLUTION*1000.0), + center.y>0?'+':'-', ROUND(center.y/RESOLUTION*1000.0), + ROUND(radius / RESOLUTION * 1000.0), + ROUND(decimalanglestart)>=1000?0:ROUND(decimalanglestart), + ROUND(decimalangleend)>=1000?0:ROUND(decimalangleend), + 3, ENDCMD); + printf("%s00000%s00000%s", TAB, JUSTIFYMARGIN, ENDCMD); + realhpxl = realvpxl = 0; + virthpxl = ROUND(end.x), virtvpxl = ROUND(end.y); + break; + case '~': /* Squiggly line */ + (void)cgets(extension); + s = extension; + n = 0; + controlpoints[n][0] = virthpxl; + controlpoints[n][1] = virtvpxl; + controlpoints[n][2] = 0.0; + while (s = extractinteger(s, &c)) { + if (!(s = extractinteger(s, &d))) { + fprintf(stderr, + "%s: odd number of spline points given\n", Whoami); + break; + } + n++; + controlpoints[n][0] = controlpoints[n-1][0] + c; + controlpoints[n][1] = controlpoints[n-1][1] + d; + controlpoints[n][2] = 0.0; /* Ignore z axis */ + } + spline(controlpoints, n, curvepoints, 499, 3); /* 2nd degree */ + fputs(VECTORON, stdout); + printf("%s%05d:%05d", PENUP, + ROUND(curvepoints[0][0]/RESOLUTION*1000.0), + ROUND(curvepoints[0][1]/RESOLUTION*1000.0)); + printf("%s03", PENWIDTH); + for (c = 1; c <= 499; c++) + printf("%s%05d:%05d", PENDOWN, + ROUND(curvepoints[c][0]/RESOLUTION*1000.0), + ROUND(curvepoints[c][1]/RESOLUTION*1000.0)); + fputs(VECTOROFF, stdout); + printf("%s00000%s00000%s\r", TAB, JUSTIFYMARGIN, ENDCMD); + virthpxl = ROUND(curvepoints[n][0]), virtvpxl = + ROUND(curvepoints[n][1]); + realhpxl = realvpxl = 0; + break; + default: + fprintf(stderr, "%s: invalid ditroff draw command %c\n", + Whoami, c); + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, 2); + break; + } + break; + case 'x': /* Device dependent commands */ + switch (c = getnonblank(stdin)) { + case 'i': /* Init - do nothing */ + while (!isspace(cgetchar())) /* Find next blank */ + ; + break; + case 'T': /* Name of typesetter. -T option */ + if (!EQ(DEVNAME, s = getstring(stdin))) { + fprintf(stderr,"%s: %s input given to ditroff filter\n", + Whoami, s); + cleanup(FontList, 2); + } + break; + case 'r': /* Resolution */ + while (!isspace(getchar())) + ; + if (getinteger(stdin) != RESOLUTION) { + fprintf(stderr, "%s: ditroff input resolution != %d\n", + Whoami, RESOLUTION); + cleanup(FontList, 2); + } + /* Order of evaluation is immaterial */ + if (getinteger(stdin) != 1 || getinteger(stdin) != 1) { + fprintf(stderr, + "%s: incorrect ditroff input increments\n", Whoami); + cleanup(FontList, 2); + } + break; + case 'p': /* Pause */ + while (!isspace(cgetchar())) + ; + break; + case 's': /* Stop */ + while ((c = getchar()) != EOF) /* Standard I/O getchar */ + ; + callcleanup(); + break; + case 't': /* Trailer */ + while (!isspace(cgetchar())) + ; + break; + case 'f': /* Load font into mount table */ + while (!isspace(cgetchar())) + ; + c = getinteger(stdin); + s = getstring(stdin); + (void)strcpy(MountTable[c], s); + /* The special font must be named S */ + if (EQ(s, "S")) + specialfont = c; + if (!findpkfont(s, 10)) /* Just check for font, any size. */ + fprintf(stderr, + "%s: could not find font %s at any magnification\n", + Whoami, s); + break; + case 'H': /* Height - QMS can't do */ + while (!isspace(cgetchar())) + ; + (void)getinteger(stdin); + break; + case 'S': /* Slant - QMS can't do */ + while (!isspace(cgetchar())) + ; + (void)getinteger(stdin); + break; + case 'X': /* Extensions */ + (void)cgets(extension); + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl); + Pxxxstring = Xxxstring = extension; + Origin[0] = virthpxl, Origin[1] = virtvpxl; + (void)yyparse(); + fputs(QUICON, stdout); + if (Orientation == 'P') + fputs(PORTRAIT, stdout); + else + fputs(LANDSCAPE, stdout); + printf("%s%c%c", TEXTPROC, '0', '0'); + printf("%s00000%05d", INITMARGVERT, Orientation == 'P' ? + 11 * 1000 : (int)(8.5 * 1000)); + printf("%s00000%05d", INITMARGHORZ, Orientation == 'P' ? + (int)(8.5 * 1000) : 11 * 1000); + printf("%s0000", CHARSPACING); + realhpxl = realvpxl = 0; + break; + default: + fprintf(stderr, "%s: invalid ditroff x command %c\n", Whoami, + c); + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, 2); + break; + } + break; + default: + fprintf(stderr, "%s: invalid ditroff command %c\n", Whoami, c); + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, 2); + break; + } + } +} + +/* Returns a pointer to a node on the FontList with the matching name, + * pointsize and orientation or NULL if not found. + */ +struct FontNode *getnodebyname(head, name, ptsize, or) +struct FontNode *head; +char *name; +int ptsize; +int or; +{ + struct FontNode *p; + + for (p = head; p; p = p->next) + if (p->localinfo && LI(p)->pointsize == ptsize && (p->flags & PORT + ? 'P' : 'L') == or && EQ(LI(p)->name, name)) + return p; + return NULL; +} + +/* Adds a new font to the font list. All the fields in the LocalInfo + * structure are filled in. If the font is loaded on startup, the blocksize + * is left as is; otherwise, the blocksize is estimated. + */ +struct FontNode *fonttolist(font, pointsize) +char *font; +int pointsize; +{ + long fontstructoffset; /* Offset at beginning of font structure */ + long funnycharoffset;/* Offset before funny_char_index_table */ + long ftell(); + int qmsfontnum, mag, ds, i, c, fontindex, encodecompare(); + short size, index; + char *fullfontpath, fontname[21], sfontname[21], *tail(), *malloc(), + descfilename[81], *findpkfont(); + Boolean extractinfo(); + void seteoffunction(), pkeofsocleanup(), desceofsocleanup(), + troffeofsocleanup(); + FILE *f; + struct dev devheader; + struct font fontheader; + struct FontNode *fn, *getfontnode(); + struct FontInfo *fi, *getfontinfo(); + + if (strlen(font) == 0 || pointsize == 0) /* One of the two has not */ + return NULL; /* been filled in yet. */ + /* If this works, we don't need to search the font directory */ + if (fn = getnodebyname(FontList, font, pointsize, Orientation)) + return fn; + if (!(fullfontpath = findpkfont(font, pointsize))) + return NULL; /* Try to continue */ + qmsfontnum = getnumfromtable(tail(fullfontpath)); + assert(qmsfontnum > 0); + if (!(fn = getfontnode(FontList, qmsfontnum, Orientation))) { + bzero((char *)(fn = (struct FontNode *)malloc((unsigned) + sizeof(struct FontNode))), sizeof(struct FontNode)); + fn->next = FontList, FontList = fn; + } + if (fn->localinfo) /* This font is already on the list */ + return fn; + else + bzero(fn->localinfo = malloc((unsigned)sizeof(struct LocalInfo)), + sizeof(struct LocalInfo)); + fn->flags |= RAM; + if (Orientation == 'P') + fn->flags |= PORT; + fn->qmsnumber = qmsfontnum; + (void)strcpy(LI(fn)->name, font); + (void)strcpy(LI(fn)->pathname, fullfontpath); + (void)extractinfo(tail(LI(fn)->pathname), fontname, sfontname, &ds, &mag); + LI(fn)->pointsize = ROUND(mag / (double)RESOLUTION * UNITWIDTH); + (void)strcpy(EOFName, fullfontpath); + seteoffunction(pkeofsocleanup); + if (!(fi = getfontinfo(fullfontpath, (EQ(Model, "QMS800") || + EQ(Model, "QMS1500")) && Orientation == 'P' || (!EQ(Model, "QMS800") && + !EQ(Model, "QMS1500")) && Orientation == 'L' ? 'X' : 'Y'))) { + FontList = FontList->next; /* Bad PK file or not readable */ + fprintf(stderr, "%s: could not open or bad PK file %s\n", Whoami, + fullfontpath); + free(fn->localinfo), free((char *)fn); + return NULL; + } + if (!(fn->flags & PRELOADED)) + fn->blocksize = fi->blocksize; + seteoffunction(troffeofsocleanup); + LI(fn)->qmsheight = fi->qmsheight; + LI(fn)->qmsbaseline = fi->qmsbaseline; + for (i = 0; i < 256; i++) { + if (fi->chararray[i].tfm > 0 || (fi->chararray[i].w > 0 && + fi->chararray[i].h > 0)) + LI(fn)->charexists[i] = TRUE; + else + LI(fn)->charexists[i] = FALSE; + LI(fn)->widths[i] = ROUND(fi->chararray[i].tfm * ((fi->ds / + (double)FIX) / FIX) / PPI * RESOLUTION * ((double)LI(fn)->pointsize + / UNITWIDTH)); + LI(fn)->bitmapsize[0][i] = fi->chararray[i].w; + LI(fn)->bitmapsize[1][i] = fi->chararray[i].h; + } + (void)sprintf(descfilename, "%s/%s", FONTDIR, "DESC.out"); + LI(fn)->maptablesize = 0; + if (!(f = fopen(descfilename, "r"))) { /* Couldn't access DESC.out! */ + static Boolean printed = FALSE; + + if (!printed) { /* Only print error message once */ + fprintf(stderr, "%s: could not open %s file \n", Whoami, + descfilename); + printed = TRUE; + } + return fn; + } + (void)strcpy(EOFName, descfilename); + seteoffunction(desceofsocleanup); + (void)cfread((char *)&devheader, sizeof(struct dev), 1, f); + (void)cfread((char *)&size, sizeof(short), 1, f); + while (size) + (void)cfread((char *)&size, sizeof(short), 1, f); + funnycharoffset = ftell(f); + assert(devheader.nchtab <= 160); + (void)fseek(f, (long)devheader.nchtab * sizeof(short) + devheader.lchname, + 1); + for (fontstructoffset = ftell(f); (i = fread((char *)&fontheader, + sizeof(struct font), 1, f)) == 1 && !EQ(LI(fn)->name, fontheader.namefont); + (void)fseek(f, 3L * fontheader.nwfont + 96 + devheader.nchtab, 1), + fontstructoffset = ftell(f)) + ; + if (i != 1) { /* font not found */ + (void)fclose(f); + seteoffunction(troffeofsocleanup); + return fn; + } + for (i = 0; i < devheader.nchtab; i++) { + (void)fseek(f, fontstructoffset + sizeof(struct font) + 3 * + fontheader.nwfont + 96 + i, 0); + if ((fontindex = cgetc(f)) == 0) + continue; + (void)fseek(f, funnycharoffset + i * sizeof(short), 0); + (void)cfread((char *)&index, sizeof(short), 1, f); + (void)fseek(f, funnycharoffset + devheader.nchtab * sizeof(short) + + index, 0); + /* The special strings are encoded, put in the maptable and + * sorted for fast lookup using a binary search. The encoding must + * preserve the uniqueness of the strings. Assuming special + * sequences are 3 bytes or less, we can put the bytes of the strings + * in the 3 low order bytes of the maptable[] word and use + * the high order byte to store the position in the font. + */ + LI(fn)->maptable[LI(fn)->maptablesize] = 0; + while ((c = cgetc(f)) != '\0') + LI(fn)->maptable[LI(fn)->maptablesize] = + LI(fn)->maptable[LI(fn)->maptablesize] << 8 | c; + LI(fn)->maptable[LI(fn)->maptablesize] &= 0xFFFFFF;/*Keep low 3 bytes*/ + (void)fseek(f, fontstructoffset + sizeof(struct font) + 2 * + fontheader.nwfont + fontindex, 0); + LI(fn)->maptable[LI(fn)->maptablesize] |= cgetc(f) << 24; /* Put font*/ + LI(fn)->maptablesize++; /* pos in top byte */ + } + (void)fclose(f); + seteoffunction(troffeofsocleanup); + qsort((char *)(LI(fn)->maptable), LI(fn)->maptablesize, sizeof(long), + encodecompare); + return fn; +} + +/* Returns the full pathname of the font whose size most closely matches that + * passed as a parameter. Returns NULL if it can't open the directory or it + * cannot find the font at any magnification. The return value is static and + * overwritten with each call. + */ +char *findpkfont(fontname, pointsize) +char *fontname; +int pointsize; +{ + int closestnumber = MAX_INTEGER; + int desiredmagnification = ROUND(RESOLUTION * pointsize / + (double)UNITWIDTH); + static char returnvalue[101]; + DIR *dirp; + struct direct *direntry; + char dirfname[81], dirsfname[81]; + Boolean extractinfo(); + int dirdsize, dirmag; + + returnvalue[0] = '\0'; + if (dirp = opendir(PKDir)) { + for (direntry = readdir(dirp); direntry; direntry = readdir(dirp)) { + if (direntry->d_namlen < 5 || !extractinfo(direntry->d_name, + dirfname, dirsfname, &dirdsize, &dirmag) || !EQ(dirfname, + fontname)) + continue; + if (ABS(dirmag - desiredmagnification) < closestnumber) { + closestnumber = ABS(dirmag - desiredmagnification); + (void)sprintf(returnvalue, "%s/%s", PKDir, + direntry->d_name); + } + } + closedir(dirp); + } + if (strlen(returnvalue) > 0) + return returnvalue; + return NULL; +} + +/* Adjusts printer coordinates so they correspond to ditroff's coordinates. It + * adjusts the real coordinates if necessary. + */ +void adjust(realh, realv, virth, virtv) +int *realh, *realv, virth, virtv; +{ + if (*realh != virth) { + printf("%s%05d%s", TAB, ROUND(virth / (double)RESOLUTION * 1000.0), + ENDCMD); + *realh = virth; + } + if (*realv != virtv) { + printf("%s%05d%s", JUSTIFYMARGIN, ROUND(virtv / (double)RESOLUTION * + 1000.0), ENDCMD); + *realv = virtv; + } +} + +/* Compares two encodings of troff special sequences */ +int encodecompare(one, two) +long *one, *two; +{ + return (*one & 0xFFFFFF) == (*two & 0xFFFFFF) ? 0 : (*one & 0xFFFFFF) + < (*two & 0xFFFFFF) ? -1 : 1; +} + +/* Looks up a special sequence in the maptable and returns the position + * found. It returns -1 if not found. This routine uses a binary search. + */ +int lookup(table, numvalues, key) +long table[]; +int numvalues; +char *key; +{ + int start = 0, end = numvalues - 1, midpoint; + long keyencoded; /* An encoded version of the key */ + char *p; + + for (p = key, keyencoded = 0; p && *p; p++) + keyencoded = (keyencoded << 8) | *p; + while (start <= end) { + midpoint = (start + end) / 2; + if ((keyencoded & 0xFFFFFF) == (table[midpoint] & 0xFFFFFF)) + return midpoint; + if ((keyencoded & 0xFFFFFF) > (table[midpoint] & 0xFFFFFF)) + start = midpoint + 1; + else + end = midpoint - 1; + } + return -1; +} + +/* Downloads a font */ +Boolean download(fn) +struct FontNode *fn; +{ + struct CharInfo *ci; + char *tail(), *strcpy(); + void resetpkfile(), seteoffunction(), + downloadpkeofsocleanup(), troffeofsocleanup(); + int downloadinterrupt(), callcleanup(); + int downloadtype, result, i, truebyteswide, bytestooutput, + row, bytes; + + if (!fn || fn->flags & LOADED || !(fn->flags & RAM) || (fn->flags & PORT ? + 'P' : 'L') != Orientation) + return FALSE; + resetpkfile(); + downloadtype = ((EQ(Model, "QMS800") || EQ(Model, "QMS1500")) && + Orientation == 'P' || (!EQ(Model, "QMS800") && !EQ(Model, "QMS1500")) + && Orientation == 'L' ? 'X' : 'Y'); + DownLoadFNum = fn->qmsnumber; + (void)sigblock(SIGINT); /* Temporarily block interrupts */ + SigStruct.sv_handler = downloadinterrupt; + (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL); + (void)strcpy(EOFName, LI(fn)->pathname); + seteoffunction(downloadpkeofsocleanup); + /* #defining ASCIILOAD causes ASCII characters to be used for the download + * sequence. Twice as many characters must be sent but it is useful for + * looking at the output when debugging. Also, you can actually see the + * bitmaps in the output. ASCII loading must be used when you can't get + * hardware flow control to work. Far out. + */ +#ifdef ASCIILOAD + fputs(FREEFORM, stdout); +#else + fputs(EIGHTBITON, stdout); +#endif + printf("%s%05d%c0%-4.4s%03d%03dT", DOWNLOAD, fn->qmsnumber, Orientation, + tail(LI(fn)->pathname), LI(fn)->qmsheight, LI(fn)->qmsbaseline); + (void)sigsetmask(sigblock(0) & ~SIGINT); /* Unblock interrupts */ + while ((result = getnextcharinfo(LI(fn)->pathname, downloadtype, &ci)) != + 1) + switch (result) { + case 2: + fprintf(stderr, "%s: could not open %s\n", Whoami, + LI(fn)->pathname); + return FALSE; + case 3: + fprintf(stderr, "%s: %s is not a PK file\n", Whoami, + LI(fn)->pathname); + return FALSE; + case 4: + fprintf(stderr, "%s: %s PK version is incorrect\n", Whoami, + LI(fn)->pathname); + return FALSE; + case 0: /* Ok. Got a bitmap */ + if (ci->h == 0 || ci->w == 0) + continue; + putchar(','); + printf("%02X%03d", ci->cc, LI(fn)->widths[ci->cc]); + if (downloadtype == 'X') { + printf("%03d%03d", ci->h, ci->w); + printf("%c%03d", LI(fn)->qmsbaseline - ci->voff >= 0 ? '+' + : '-', ABS(LI(fn)->qmsbaseline - ci->voff)); + printf("%c%03d", -ci->hoff >= 0 ? '+' : '-', ABS(-ci->hoff)); + } else { + printf("%03d%03d", ci->w, ci->h); + printf("%c%03d", -ci->hoff >= 0 ? '+' : '-', ABS(ci->hoff)); + printf("%c%03d", (LI(fn)->qmsheight - LI(fn)->qmsbaseline) - + (ci->h - ci->voff) >= 0 ? '+' : '-', ABS((LI(fn)->qmsheight + - LI(fn)->qmsbaseline) - (ci->h - ci->voff))); + i = ci->w, ci->w = ci->h, ci->h = i; /* Swaparoo! */ + } + truebyteswide = ci->w + 7 >> 3; /* >> divides by 8 */ + bytestooutput = (ci->w + 15 >> 4) * 2; /* >> divides by 16 */ +#ifdef ASCIILOAD + for (row = 0; row < ci->h; row++) { +#else + for (row = 0; row < ci->h; row++) +#endif + for (bytes = 0; bytes < bytestooutput; bytes++) { + if (bytes == truebyteswide - 1) + *(ci->bitmap + row * truebyteswide + bytes) &= + 0xFF<<7-(ci->w+7)%8; + if (bytes < truebyteswide) { + i = *(ci->bitmap + row * truebyteswide + bytes) & + 0xFF; +#ifdef ASCIILOAD + printf("%c%c", "0123456789ABCDEF"[i >> 4], + "0123456789ABCDEF"[i & 0xF]); +#else + if (i == '^') + printf("^^"); + else + (void)putchar(i); +#endif + } else +#ifdef ASCIILOAD + printf("00"); +#else + (void)putchar(0); +#endif + } +#ifdef ASCIILOAD + putchar('\n'); + } +#endif + break; + } /* End switch */ +#ifdef ASCIILOAD + printf("%s%s", ENDCMD, FREEOFF); +#else + printf("%s%s", ENDCMD, EIGHTBITOFF); +#endif + putchar('\r'); /* Ends the pass */ + (void)sigblock(SIGINT); + printf("%s00000%s", TAB, ENDCMD); + printf("%s00000%s", JUSTIFYMARGIN, ENDCMD); + SigStruct.sv_handler = callcleanup; + (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL); + seteoffunction(troffeofsocleanup); + CurRamBlocks += fn->blocksize; + fn->flags |= LOADED; + (void)sigsetmask(sigblock(0) & ~SIGINT); + return TRUE; +} + +/* The following are routines called when a SIGINT is received or EOF is + * unexpectedly encountered when reading a file. + */ +simplyexit() +{ + exit(SUCCEED); +} + +callcleanup() +{ + void cleanup(); + + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, SUCCEED); /* Interrupting a program is not an error */ +} + +void troffeofsocleanup() +{ + fprintf(stderr, "%s: unexpected EOF when reading ditroff file\n", Whoami); + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, 2); +} + +void pkeofsocleanup() +{ + fprintf(stderr, "%s: unexpected EOF when reading PK file %s\n", Whoami, + EOFName); + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, 2); +} + +void desceofsocleanup() +{ + fprintf(stderr, "%s: unexpected EOF when reading DESC.out file %s\n", + Whoami, EOFName); + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, 2); +} + +downloadinterrupt() +{ + fputs(ENDCMD, stdout); +#ifdef ASCIILOAD + fputs(FREEOFF, stdout); +#else + fputs(EIGHTBITOFF, stdout); +#endif + printf("%s%05d%c%s", DOWNLOAD, DownLoadFNum, Orientation, ENDCMD); + callcleanup(); +} + +void downloadpkeofsocleanup() +{ + fputs(ENDCMD, stdout); +#ifdef ASCIILOAD + fputs(FREEOFF, stdout); +#else + fputs(EIGHTBITOFF, stdout); +#endif + printf("%s%05d%c%s", DOWNLOAD, DownLoadFNum, Orientation, ENDCMD); + pkeofsocleanup(); +} + +#include "xxx.c" diff --git a/dviware/quicspool/src/of.c b/dviware/quicspool/src/of.c new file mode 100644 index 0000000000..9bb125fc7e --- /dev/null +++ b/dviware/quicspool/src/of.c @@ -0,0 +1,271 @@ +/* "of" filter - prints banner page */ +#ifndef lint +static char *rcs = "$Header: of.c,v 1.1 88/01/15 13:04:45 simpson Rel $"; +#endif +/* +$Log: of.c,v $ + * Revision 1.1 88/01/15 13:04:45 simpson + * initial release + * + * Revision 0.2 87/12/22 15:50:06 simpson + * added pitch reset + * + * Revision 0.1 87/12/11 18:31:07 simpson + * beta test + * +*/ +#include <stdio.h> +#include <signal.h> +#include <sgtty.h> +#include <sys/file.h> +#include <local/standard.h> +#include <local/profile.h> +#include <local/qms.h> + +static struct Speeds { + int speed; + int code; +} Speeds[] = { + 50, B50, + 75, B75, + 110, B110, + 134, B134, + 300, B300, + 600, B600, + 1200, B1200, + 2400, B2400, + 4800, B4800, + 9600, B9600, + 19200, EXTA, + 0, 0 +}; + +char *Whoami; + +main(argc, argv) +int argc; +char *argv[]; +{ + Boolean oinlist(), vinlist(); + struct optnode *p; + struct qmsopc *opc; + void setoption(), qmsopcfree(); + int c, fc, fs, xc, xs, br; + int portraitfont = 1204; + float portraitpitch = 12.0; + FILE *f; + char *readline, *queue, bp[1024]; + PROFILE_VALUE *v, *class1, *class2, *class3, *class4, + *getbindingvalue(); + struct sgttyb sgtty; + + Whoami = argv[0]; + while ((c = getopt(argc, argv, "w:l:")) != EOF) + switch (c) { + case 'w': + case 'l': + break; + case '?': + exit(2); + } + if ((v = getbindingvalue("portraitfont")) && v->class == PROFILE_INTEGER) + portraitfont = v->value.i; + if ((v = getbindingvalue("portraitpitch")) && (v->class == PROFILE_INTEGER + || v->class == PROFILE_FLOAT)) + if (v->class == PROFILE_INTEGER) + portraitpitch = v->value.i; + else + portraitpitch = v->value.f; + class1 = getbindingvalue("class1"); + class2 = getbindingvalue("class2"); + class3 = getbindingvalue("class3"); + class4 = getbindingvalue("class4"); + if (!(v = getbindingvalue("readline")) || v->class != PROFILE_STRING && + v->class != PROFILE_OTHER) { + fprintf(stderr, + "%s: missing or invalid readline binding in configuration file\n", + Whoami); + exit(2); + } +#if defined(sun) + (void)flock(fileno(stdout), LOCK_EX); +#endif + readline = v->value.s; + if (!(f = fopen(readline, "r"))) { + fprintf(stderr, "%s: cannot open read tty %s\n", Whoami, readline); + exit(2); + } + if (!(v = getbindingvalue("queuename")) || v->class != PROFILE_STRING + && v->class != PROFILE_OTHER) { + fprintf(stderr, + "%s: missing or invalid queuename binding in configuration file\n", + Whoami); + exit(2); + } + queue = v->value.s; + (void)ioctl(fileno(f), TIOCGETP, &sgtty); + if (pgetent(bp, queue) != 1) { + fprintf(stderr, "%s: can't find queue entry in printcap file!\n", + Whoami); + exit(2); + } + /* Set up the tty settings on the debugger port to be the same as the */ + /* daughter board port, except use hardware flow control (DTR) on the */ + /* daughter board port and software flow control (XON/XOFF) on the */ + /* debugger port. Hardware flow control allows us to send ^S and ^Q */ + /* to the QMS printer but since the debugger port simply passes */ + /* through the data it receives, it cannot use hardware flow control */ + /* and must use ^S/^Q. Set up the debugger port tty settings as in */ + /* the /etc/printcap file but always turn TANDEM on and LMDMBUF off */ + /* on the debugger port. */ + if ((fc = tgetnum("fc")) != -1) + sgtty.sg_flags &= ~fc; + if ((fs = tgetnum("fs")) != -1) + sgtty.sg_flags |= fs; + sgtty.sg_flags |= RAW | TANDEM; /* Always! */ + if ((br = tgetnum("br")) != -1) + sgtty.sg_ispeed = sgtty.sg_ospeed = convertspeed(br); + (void)ioctl(fileno(f), TIOCSETP, &sgtty); + if ((xs = tgetnum("xs")) != -1) + (void)ioctl(fileno(f), TIOCLBIS, &xs); + if ((xc = tgetnum("xc")) != -1) + (void)ioctl(fileno(f), TIOCLBIC, &xc); + c = LMDMBUF; + (void)ioctl(fileno(f), TIOCLBIC, &c); /* Always! */ +#ifdef pyr + /* Pyramid specific ioctls that must be set to get everything to */ + /* really work. */ + /* Use hardware flow control for the daughter board port. */ +#ifdef ASCIILOAD + c = 1; + (void)ioctl(fileno(stdout), TIOCHXON, &c); +#else + c = 1; + (void)ioctl(fileno(stdout), TIOCHCTS, &c); +#endif + /* Use software flow control for the debugger port. */ + c = 2; + (void)ioctl(fileno(f), TIOCHXON, &c); +#endif + if (!qmsopen(fileno(stdout), fileno(f))) { + fprintf(stderr, "%s: qmsopen() failed\n", Whoami); + exit(2); + } + if (!(opc = qmsopc())) { + fprintf(stderr, "%s: failed to read option class info\n", Whoami); + exit(2); + } + fputs(QUICON, stdout); + /* First turn off the option classes that should not be turned on */ + for (p = opc->OC1; p; p = p->next) + if (!vinlist(class1, p->option)) + setoption(1, p->option, FALSE); + for (p = opc->OC2; p; p = p->next) + if (!vinlist(class2, p->option)) + setoption(2, p->option, FALSE); + for (p = opc->OC3; p; p = p->next) + if (!vinlist(class3, p->option)) + setoption(3, p->option, FALSE); + for (p = opc->OC4; p; p = p->next) + if (!vinlist(class4, p->option)) + setoption(4, p->option, FALSE); + /* Now enable the option classes that should be turned on */ + for (v = class1; v; v = v->next) + if (v->class == PROFILE_INTEGER) + if (!oinlist(opc->OC1, (int)v->value.i)) + setoption(1, (int)v->value.i, TRUE); + for (v = class2; v; v = v->next) + if (v->class == PROFILE_INTEGER) + if (!oinlist(opc->OC2, (int)v->value.i)) + setoption(2, (int)v->value.i, TRUE); + for (v = class3; v; v = v->next) + if (v->class == PROFILE_INTEGER) + if (!oinlist(opc->OC3, (int)v->value.i)) + setoption(3, (int)v->value.i, TRUE); + for (v = class4; v; v = v->next) + if (v->class == PROFILE_INTEGER) + if (!oinlist(opc->OC4, (int)v->value.i)) + setoption(4, (int)v->value.i, TRUE); + fputs(PORTRAIT, stdout); + printf("%s00000", SYNTAX); + printf("%s%04d", LINESPACING, (int)(6.02 * 100)); + printf("%s0000011000", INITMARGVERT); + printf("%s0025008500", INITMARGHORZ); + printf("%s%d%s", DEFFONT, portraitfont, ENDCMD); + printf("%s%04d", CHARSPACING, (int)(v->value.f * 100.0)); + fputs(FREEOFF, stdout); + fputs(QUICOFF, stdout); + while ((c = getchar()) != EOF) { + if (c == '\n') + printf("\r\n"); + else if (c == 031) + if ((c = getchar()) == '\1') { + fputs(QUICON, stdout); + printf("%s0000008500", INITMARGHORZ); + fputs(QUICOFF, stdout); + (void)fflush(stdout); + (void)kill(getpid(), SIGSTOP); + continue; + } else { + (void)putchar(031); + (void)ungetc(c, stdout); + } + else + (void)putchar(c); + } + qmsopcfree(opc); + qmsclose(); +#if defined(sun) + (void)flock(fileno(stdout), LOCK_UN); +#endif + exit(SUCCEED); +} + +/* Returns true if the option class number is set in the passed list */ +static Boolean oinlist(list, option) +struct optnode *list; +int option; +{ + for (; list; list = list->next) + if (list->option == option) + return TRUE; + return FALSE; +} + +/* Returns true if option class number is set in the passed list */ +static Boolean vinlist(list, option) +PROFILE_VALUE *list; +int option; +{ + for (; list; list = list->next) + if (list->class == PROFILE_INTEGER && list->value.i == option) + return TRUE; + return FALSE; +} + +/* Enables or disables an option */ +static void setoption(class, option, enable) +int class; +int option; +int enable; +{ + if (class * 100 + option < 149 || 499 < class * 100 + option) + return; + printf("%s%s%d", PCONFIG, enable ? "" : ":", class * 100 + option); + fprintf(stderr, "%s: Warning: %s printer option (%d,%d)\n", Whoami, + enable ? "enabling" : "disabling", class, option); +} + +/* Converts a baud rate from a number to the number you need to pass to + * ioctl(2). + */ +static int convertspeed(b) +int b; +{ + struct Speeds *s; + + for (s = Speeds; s->speed; s++) + if (s->speed == b) + return s->code; + return B9600; +} diff --git a/dviware/quicspool/src/pk.c b/dviware/quicspool/src/pk.c new file mode 100644 index 0000000000..09d1b20866 --- /dev/null +++ b/dviware/quicspool/src/pk.c @@ -0,0 +1,475 @@ +#ifndef lint +static char *rcs = "$Header: pk.c,v 1.1 88/01/15 13:04:52 simpson Rel $"; +#endif +/* +$Log: pk.c,v $ + * Revision 1.1 88/01/15 13:04:52 simpson + * initial release + * + * Revision 0.1 87/12/11 18:31:09 simpson + * beta test + * +*/ +#include <stdio.h> +#include <assert.h> +#include <local/standard.h> +#include "constants.h" +#include "fontinfo.h" +#include "pk.h" + +/* Routines pertaining to PK files. */ + +static int BitNumber; /* Count of bits read in a byte */ +static int Byte; /* Byte currently reading bits or nybbles from */ +static int RepeatCount; /* Count found during unpacking of packed number */ + +/* Resets the bit count so bit and nybble reading start on a byte boundary. */ +static void resetbitcount() +{ + BitNumber = 0; +} + +/* Returns the next nybble from the file. This routine uses the cgetc() + * function so an appropriate error routine will need to be set. + */ +static int getnyb(f) +FILE *f; +{ + if (BitNumber == 0) { + Byte = cgetc(f); + BitNumber = 8; + } + if (BitNumber == 8) { + BitNumber -= 4; + return Byte >> 4 & 0xF; + } else { + BitNumber -= 4; + return Byte & 0xF; + } +} + +/* Returns true if the next bit is on, false otherwise. This routine uses the + * cgetc() function so an appropriate error routine will need to be set. + */ +static Boolean getbit(f) +FILE *f; +{ + if (BitNumber == 0) { + Byte = cgetc(f); + BitNumber = 8; + } + return Byte & 1 << --BitNumber ? TRUE : FALSE; +} + +/* Returns the next packed number from the file f. The global variable + * RepeatCount is set appropriately if a repeat count is found. This routine + * uses the cgetc() function so an appropriate error routine will need to be + * set. + */ +static int pkpackednum(f, dynf) +register FILE *f; +register int dynf; +{ + register int i, j; + + i = getnyb(f); + if (i == 0) { + do { + j = getnyb(f); + i++; + } while (j == 0); + while (i-- > 0) + j = (j << 4) + getnyb(f); + return j - 15 + ((13 - dynf) << 4) + dynf; + } else if (i <= dynf) + return i; + else if (i < 14) + return ((i - dynf - 1) << 4) + getnyb(f) + dynf + 1; + else { + if (i == 14) + RepeatCount = pkpackednum(f, dynf); + else + RepeatCount = 1; + return pkpackednum(f, dynf); + } + /* NOTREACHED */ +} + +/* Returns information about a PK file or NULL if it couldn't open the file + * or the file is an invalid PK file. The information returned is static and + * is overwritten with each call. Downloadtype should be 'X' or 'Y' (see the + * QMS Programming Manual). This function uses the cgetc() routine so an + * appropriate error recovery function should be set. + */ +struct FontInfo *getfontinfo(filename, downloadtype) +char *filename; +int downloadtype; +{ + unsigned long uinteger(), li, lk; + long integer(), pl, cc; + static struct FontInfo fi; + FILE *f; + int wordsneeded = 0, i, j, command, flag; + int heightstorage[256][2]; /* 0=h,1=voff f/each char*/ + int largestvoff; /* Largest voff of all chars */ + + if (!(f = fopen(filename, "r"))) + return NULL; + if (cgetc(f) != PKPRE || cgetc(f) != PKID) { + (void)fclose(f); + return NULL; + } + bzero((char *)&fi, sizeof(struct FontInfo)); + bzero((char *)heightstorage, sizeof(heightstorage)); + for (i = 0, j = cgetc(f); i < j; i++) + fi.comment[i] = cgetc(f); + fi.comment[i] = '\0'; + fi.ds = integer(f, 4); + fi.cs = integer(f, 4); + fi.hppp = integer(f, 4); + fi.vppp = integer(f, 4); + fi.numchars = fi.qmsheight = largestvoff = 0; + while ((command = cgetc(f)) != PKPOST) + if (0 <= command && command <= 239) { + flag = command; + if ((flag & 0x7) == 0x7) { /* Long format preamble */ + pl = integer(f, 4); + cc = integer(f, 4); + fi.chararray[cc].tfm = integer(f, 4); + fi.chararray[cc].dx = integer(f, 4); + fi.chararray[cc].dy = integer(f, 4); + fi.chararray[cc].w = integer(f, 4); + fi.chararray[cc].h = integer(f, 4); + fi.chararray[cc].hoff = integer(f, 4); + fi.chararray[cc].voff = integer(f, 4); + (void)fseek(f, pl - 28, 1); + } else if (0 <= (flag & 0x7) && (flag & 0x7) <= 3) { /* Short */ + pl = cgetc(f) | (flag & 0x3) << 8; + cc = cgetc(f); + fi.chararray[cc].tfm = uinteger(f, 3); + fi.chararray[cc].dx = fi.chararray[cc].dy = cgetc(f) * SPOINT; + fi.chararray[cc].w = cgetc(f); + fi.chararray[cc].h = cgetc(f); + fi.chararray[cc].hoff = integer(f, 1); + fi.chararray[cc].voff = integer(f, 1); + (void)fseek(f, pl - 8, 1); + } else { /* Extended short form */ + pl = uinteger(f, 2) | (flag & 0x3) << 16; + cc = cgetc(f); + fi.chararray[cc].tfm = uinteger(f, 3); + fi.chararray[cc].dx = fi.chararray[cc].dy = uinteger(f, 2) + * SPOINT; + fi.chararray[cc].w = uinteger(f, 2); + fi.chararray[cc].h = uinteger(f, 2); + fi.chararray[cc].hoff = integer(f, 2); + fi.chararray[cc].voff = integer(f, 2); + (void)fseek(f, pl - 13, 1); + } + assert(0 <= cc && cc <=255); + fi.numchars++; + fi.qmsheight = MAX(fi.qmsheight, fi.chararray[cc].h); + largestvoff = MAX(largestvoff, fi.chararray[cc].voff); + heightstorage[cc][0] = fi.chararray[cc].h; + heightstorage[cc][1] = fi.chararray[cc].voff; + if (downloadtype == 'Y') + wordsneeded += (int)((fi.chararray[cc].h + 15.0) / 16.0) * + fi.chararray[cc].w; + else + wordsneeded += (int)((fi.chararray[cc].w + 15.0) / 16.0) * + fi.chararray[cc].h; + } else + switch (command) { + case PKXXX1: + case PKXXX2: + case PKXXX3: + case PKXXX4: + for (li = 0, lk = uinteger(f, command - PKXXX1 + 1); li < + lk; li++) + (void)cgetc(f); + break; + case PKYYY: + (void)uinteger(f, 4); + break; + case PKNOOP: + break; + default: + (void)fclose(f); + return NULL; + } + wordsneeded += 800.0 / 2.0 + (fi.numchars * (14.0 + 12.0)) / 2.0; + fi.blocksize = CEILING((wordsneeded * 2.0) / 1024.0); + fi.qmsbaseline = largestvoff; + for (li = 0; li < 256; li++) + fi.qmsheight = MAX(fi.qmsheight, largestvoff + (heightstorage[li][0] + - heightstorage[li][1])); + (void)fclose(f); + return &fi; +} + +/* This routine takes a PK font name and extracts the information + * contained in its naming convention. PK fonts are named like + * <font name><optional design size>.<magnification>pk. The first + * parameter is the font name. This is the only input parameter. The + * following output parameters are the name of the font (including the + * optional design size), the name of the font (without the design size), + * the design size and the magnification. For example, parameter + * cmr10.200pk would return the values + * fontname "cmr10" + * shortfontname "cmr" + * designsize 10 + * magnification 200 + * The function returns TRUE if it was successful parsing the name, FALSE + * otherwise. The designsize returned will be -1 if it is left out. + */ +Boolean extractinfo(fullfontname, fontname, shortfontname, designsize, +magnification) +char *fullfontname; +char *fontname; +char *shortfontname; +int *designsize; +int *magnification; +{ + char *p, *strcpy(); + + if (sscanf(fullfontname, "%[^0123456789.]", shortfontname) != 1) + return FALSE; + p = &fullfontname[strlen(shortfontname)]; + if ('0' <= *p && *p <= '9') { + if (sscanf(p, "%d", designsize) != 1) + return FALSE; + while ('0' <= *p && *p <= '9') + p++; + } else + *designsize = -1; + if (*designsize != -1) + (void)sprintf(fontname, "%s%d", shortfontname, *designsize); + else + (void)strcpy(fontname, shortfontname); + if (*p != '.') + return FALSE; + else + p++; + if (sscanf(p, "%d", magnification) != 1) + return FALSE; + while ('0' <= *p && *p <= '9') + p++; + if (!EQ(p, "pk")) + return FALSE; + return TRUE; +} + +static FILE *PkFilePtr; /* File pointer used in resetpkfile() + * and getnextcharinfo() */ +static struct CharInfo CInfo; /* Structure returned to the user */ + +/* Resets the getnextcharinfo() function so it reopens the PK file */ +void resetpkfile() +{ + if (PkFilePtr) { + (void)fclose(PkFilePtr), PkFilePtr = NULL; + if (CInfo.bitmap) + free(CInfo.bitmap), CInfo.bitmap = NULL; + } +} + +/* This function gets information on the next character in a font. If the + * font file is not already opened, it will open the font file. The + * downloadtype should be 'X' or 'Y'. The routine allocates and deallocates + * memory for the character bitmap itself, so you needn't worry about it. + * The filename parameter is only consulted when the routine is first called + * to get the information on the first character. If you wish to read from a + * new PK file, you must use the resetpkfile() function. The routine returns + * 0 on success, 1 if there are no more characters, 2 if the PK file could not + * be opened, 3 if the file is not a PK file and 4 if the PK version is + * incorrect. This routine calls the cgetc() function so the error routine + * should be set appropriately. + */ +int getnextcharinfo(filename, downloadtype, charinfo) +char *filename; +int downloadtype; +struct CharInfo **charinfo; +{ + unsigned long uinteger(); + char *malloc(); + int command, flag, dynf, packednum; + long pl, li, lj, integer(); + register Boolean black; + register char *bitmap, *rowmap, *putbyte; + register int i, j, k, currentw, currenth, mask; + register long w, h; + + if (!PkFilePtr) { + if (!(PkFilePtr = fopen(filename, "r"))) + return 2; + if (cgetc(PkFilePtr) != PKPRE) { + (void)fclose(PkFilePtr), PkFilePtr = NULL; + return 3; + } + if (cgetc(PkFilePtr) != PKID) { + (void)fclose(PkFilePtr), PkFilePtr = NULL; + return 4; + } + for (i = 0, j = cgetc(PkFilePtr); i < j; i++) /* Comment */ + (void)cgetc(PkFilePtr); + (void)integer(PkFilePtr, 4); /* Design size */ + (void)integer(PkFilePtr, 4); /* Checksum */ + (void)integer(PkFilePtr, 4); /* hppp */ + (void)integer(PkFilePtr, 4); /* vppp */ + } else if (CInfo.bitmap) + free(CInfo.bitmap), CInfo.bitmap = NULL; +tryagain: + if ((command = cgetc(PkFilePtr)) == PKPOST) { /* No more chars */ + (void)fseek(PkFilePtr, -1L, 1); /* Back up by 1 byte */ + return 1; + } + if (0 <= command && command <= 239) { + flag = command; + dynf = (flag & DYNF) >> 4; + if ((flag & 0x7) == 0x7) { /* Long format preamble */ + CInfo.preambletype = plong; + pl = integer(PkFilePtr, 4); + CInfo.cc = integer(PkFilePtr, 4); + CInfo.tfm = integer(PkFilePtr, 4); + CInfo.dxordm = integer(PkFilePtr, 4); + CInfo.dy = integer(PkFilePtr, 4); + CInfo.w = integer(PkFilePtr, 4); + CInfo.h = integer(PkFilePtr, 4); + CInfo.hoff = integer(PkFilePtr, 4); + CInfo.voff = integer(PkFilePtr, 4); + if (CInfo.h == 0 || CInfo.w == 0) + (void)fseek(PkFilePtr, pl - 28L, 1); + } else if (0 <= (flag & 0x7) && (flag & 0x7) <= 3) { /* Short */ + CInfo.preambletype = pshort; + pl = cgetc(PkFilePtr) | (flag & 0x3) << 8; + CInfo.cc = cgetc(PkFilePtr); + CInfo.tfm = uinteger(PkFilePtr, 3); + CInfo.dxordm = cgetc(PkFilePtr); + CInfo.w = cgetc(PkFilePtr); + CInfo.h = cgetc(PkFilePtr); + CInfo.hoff = integer(PkFilePtr, 1); /* integer() returns */ + CInfo.voff = integer(PkFilePtr, 1); /* signed values */ + if (CInfo.h == 0 || CInfo.w == 0) + (void)fseek(PkFilePtr, pl - 8L, 1); + } else { /* Extended short form */ + CInfo.preambletype = pexshort; + pl = uinteger(PkFilePtr, 2) | (flag & 0x3) << 16; + CInfo.cc = cgetc(PkFilePtr); + CInfo.tfm = uinteger(PkFilePtr, 3); + CInfo.dxordm = uinteger(PkFilePtr, 2); + CInfo.w = uinteger(PkFilePtr, 2); + CInfo.h = uinteger(PkFilePtr, 2); + CInfo.hoff = integer(PkFilePtr, 2); + CInfo.voff = integer(PkFilePtr, 2); + if (CInfo.h == 0 || CInfo.w == 0) + (void)fseek(PkFilePtr, pl - 13L, 1); + } + assert(pl > 0); + assert(CInfo.h >= 0 && CInfo.w >= 0); + assert(0 <= CInfo.cc && CInfo.cc <= 255); + *charinfo = &CInfo; + h = CInfo.h, w = CInfo.w; + if (h == 0 || w == 0) + return 0; + if (downloadtype == 'X') { + /* Shifting right 3 divides by 8 faster than division */ + bitmap = CInfo.bitmap = malloc((unsigned)((w+7>>3)*h)); + if (dynf == 14) { + bzero(bitmap, (int)((w+7>>3)*h)); + for (i = 0; i < h; i++) + for (j = 0; j < w; j++) + if (getbit(PkFilePtr)) + *(bitmap + i*(w+7>>3) + (j>>3)) |= 1<<7-j%8; + } else { /* Get normally packed raster */ + black = flag & BRUNCOUNT; + rowmap = malloc((unsigned)(w+7>>3)); + bzero(rowmap,(int)(w+7>>3)); + currenth = currentw = RepeatCount = 0; + while (currenth < h && currentw < w) { + packednum = pkpackednum(PkFilePtr, dynf); + for (i = 0; i < packednum; i++) { + if (black) + *(rowmap + (currentw>>3)) |= 1<<7-currentw%8; + if (++currentw == w) { + for (j = 0; j < RepeatCount + 1; j++) + bcopy(rowmap, bitmap + currenth++ * (w+7>>3), + (w+7>>3)); + bzero(rowmap, (int)(w+7>>3)); + currentw = RepeatCount = 0; + } + } + black = !black; + } + free(rowmap); + } + } else { /* Y orientation */ + bitmap = CInfo.bitmap = malloc((unsigned)((h+7>>3)*w)); + bzero(bitmap, (int)((h+7>>3)*w)); + if (dynf == 14) { /* Get raster by bits */ + for (i = 0; i < h; i++) + for (j = 0; j < w; j++) + if (getbit(PkFilePtr)) { + putbyte = bitmap + j*(h+7>>3) + (h-(i+1)>>3); + *putbyte |= 1<<7-((h+7)-i)%8; + } + } else { /* Get normally packed raster */ + black = flag & BRUNCOUNT; + rowmap = malloc((unsigned)(w+7>>3)); + bzero(rowmap, (int)(w+7>>3)); + currenth = currentw = RepeatCount = 0; + while (currenth < h && currentw < w) { + packednum = pkpackednum(PkFilePtr, dynf); + for (i = 0; i < packednum; i++) { + if (black) { + *(rowmap + (currentw>>3)) |= 1<<7-currentw%8; + putbyte = bitmap + currentw*(h+7>>3)+ + (h-(currenth+1)>>3); + *putbyte |= 1<<7-((h+7)-currenth)%8; + } + if (++currentw == w) { + currenth++; + for (j = 0; j < RepeatCount; j++) { + for (k = 0; k < w; k++) { + if (k % 8 == 0) + mask = 0x80; + else + mask >>= 1; + if (*(rowmap + (k>>3)) & mask) { + putbyte = bitmap + k*(h+7>>3) + + (h-(currenth+1)>>3); + *putbyte |= 1<<7-((h+7)-currenth)%8; + } + } + currenth++; + } + bzero(rowmap, (int)(w+7>>3)); + currentw = RepeatCount = 0; + } + } + black = !black; + } + free(rowmap); + } /* End get normally packed raster */ + } /* End Y orientation */ + resetbitcount(); + } else /* End of if (0 <= command && command <= 239) { */ + switch (command) { + case PKXXX1: + case PKXXX2: + case PKXXX3: + case PKXXX4: + for (li = 0, lj = uinteger(PkFilePtr, command - PKXXX1 + 1); + li < lj; li++) + (void)cgetc(PkFilePtr); + goto tryagain; + case PKYYY: + (void)uinteger(PkFilePtr, 4); + goto tryagain; + default: +#ifndef lint + assert(FALSE); +#else + ; +#endif + } + return 0; +} diff --git a/dviware/quicspool/src/pk.h b/dviware/quicspool/src/pk.h new file mode 100644 index 0000000000..302f391a29 --- /dev/null +++ b/dviware/quicspool/src/pk.h @@ -0,0 +1,23 @@ +/* $Header: pk.h,v 1.1 88/01/15 13:04:56 simpson Rel $ */ +/* +$Log: pk.h,v $ + * Revision 1.1 88/01/15 13:04:56 simpson + * initial release + * + * Revision 0.1 87/12/11 18:31:10 simpson + * beta test + * +*/ +#define PKXXX1 240 +#define PKXXX2 241 +#define PKXXX3 242 +#define PKXXX4 243 +#define PKYYY 244 +#define PKPOST 245 +#define PKNOOP 246 +#define PKPRE 247 +#define PKID 89 +/* Masks */ +#define DYNF 0xF0 +#define BRUNCOUNT 0x8 /* Black run count */ +#define TWOBYTE 0x4 diff --git a/dviware/quicspool/src/pktoch.c b/dviware/quicspool/src/pktoch.c new file mode 100644 index 0000000000..510ebe91a2 --- /dev/null +++ b/dviware/quicspool/src/pktoch.c @@ -0,0 +1,100 @@ +#ifndef lint +static char *rcs = "$Header: pktoch.c,v 1.1 88/01/15 13:04:58 simpson Rel $"; +#endif +/* +$Log: pktoch.c,v $ + * Revision 1.1 88/01/15 13:04:58 simpson + * initial release + * + * Revision 0.1 87/12/11 18:31:11 simpson + * beta test + * +*/ +#include <stdio.h> +#include <local/standard.h> +#include "fontinfo.h" + +char *Usage = "Usage: %s <pk-file> <chr-file>\n"; +char *WhoAmI; +float Version = 1.0; + +main(argc, argv) +int argc; +char *argv[]; +{ + int c; + extern int optind; + void printrasters(), seteoffunction(), eofencountered(); + FILE *output; + struct FontInfo *getfontinfo(), *fi; + + WhoAmI = argv[0]; + while ((c = getopt(argc, argv, "")) != EOF) + switch (c) { + case '?': +err: fprintf(stderr, Usage, WhoAmI); + exit(FAIL); + } + if (optind != argc - 2) + goto err; + printf("This is PKtoCH, Version %.1f\n", Version); + seteoffunction(eofencountered); + if (!(fi = getfontinfo(argv[optind], 'X'))) { + fprintf(stderr, "%s: %s is not readable or is not a pk file\n", + WhoAmI, argv[optind]); + exit(FAIL); + } + if (!(output = fopen(argv[++optind], "w"))) { + fprintf(stderr, "%s: could not open %s\n", WhoAmI, argv[optind]); + exit(FAIL); + } + fputs("Font file info :", output); + fputs(fi->comment, output); + (void)putc('\n', output); + fprintf(output, "Design Size :%ld\n", fi->ds); + fprintf(output, "Checksum :%ld\n", fi->cs); + fprintf(output, "hppp :%ld\n", fi->hppp); + fprintf(output, "vppp :%ld\n", fi->vppp); + printrasters(argv[optind - 1], output); + (void)fclose(output); + printf("All done.\n"); + exit(SUCCEED); +} + +void printrasters(infile, output) +char *infile; +FILE *output; +{ + struct CharInfo *ci; + void printbitmap(), resetpkfile(); + + resetpkfile(); + while (getnextcharinfo(infile, 'X', &ci) != 1) { + (void)putc('\f', output); + fprintf(output, "chrcode :"); + if (' ' <= ci->cc && ci->cc <= '~') + fprintf(output, "'%c'\n", (int)ci->cc); + else + fprintf(output, "%ld\n", ci->cc); + fprintf(output, "tfm width :%ld\n", ci->tfm); + if (ci->preambletype == plong) { + fprintf(output, "dx :%ld\n", ci->dxordm); + fprintf(output, "dy :%ld\n", ci->dy); + } else + fprintf(output, "dm :%ld\n", ci->dxordm); + fprintf(output, "width :%ld\n", ci->w); + fprintf(output, "height :%ld\n", ci->h); + fprintf(output, "h offset :%ld\n", ci->hoff); + fprintf(output, "v offset :%ld\n", ci->voff); + fprintf(output, "+\n"); + printbitmap(output, ci->bitmap, (int)ci->w, (int)ci->h); + } +} + +void eofencountered() +{ + fprintf(stderr, "%s: premature eof encountered in PK file\n", WhoAmI); + exit(FAIL); +} + + diff --git a/dviware/quicspool/src/profile.c b/dviware/quicspool/src/profile.c new file mode 100644 index 0000000000..7f6440c539 --- /dev/null +++ b/dviware/quicspool/src/profile.c @@ -0,0 +1,40 @@ +#ifndef lint +static char *rcs = "$Header: profile.c,v 1.1 88/01/15 13:05:09 simpson Rel $"; +#endif +/* +$Log: profile.c,v $ + * Revision 1.1 88/01/15 13:05:09 simpson + * initial release + * + * Revision 0.1 87/12/11 18:31:15 simpson + * beta test + * +*/ +/* Profile(3) related routines */ + +#include <stdio.h> +#include <local/profile.h> + +/* Returns the value of a binding in the configuration stanza with the key + * equal to the formal parameter name. It returns NULL if unsuccessful. + */ +PROFILE_VALUE *getbindingvalue(key) +char *key; +{ + FILE *config; + static PROFILE_STANZA *s; + PROFILE_BINDING *b; + + if (!s) + if (config = fopen("configuration", "r")) { + if (!(s = profile_read_stanza(config))) { + (void)fclose(config); + return NULL; + } + (void)fclose(config); + } else + return NULL; + if (b = profile_has_binding(s, key)) + return b->value; + return NULL; +} diff --git a/dviware/quicspool/src/qms.c b/dviware/quicspool/src/qms.c new file mode 100644 index 0000000000..1159abef85 --- /dev/null +++ b/dviware/quicspool/src/qms.c @@ -0,0 +1,66 @@ +#ifndef lint +static char *rcs = "$Header: qms.c,v 1.1 88/01/15 13:05:14 simpson Rel $"; +#endif +/* +$Log: qms.c,v $ + * Revision 1.1 88/01/15 13:05:14 simpson + * initial release + * + * Revision 0.1 87/12/11 18:31:16 simpson + * beta test + * +*/ + +/* QMS printer routines */ + +#include <stdio.h> +#include <local/qms.h> +#include "fontnode.h" + + +/* Sets up the printer to portrait mode in a sane state. After the + * completion of a job, the banner page of the next job may be printed + * without running the "of" filter so we must setup the printer as the "of" + * filter does. Also, switch the tray offset in this routine. This + * routine is called before every filter exits. + */ +void sanestate(portfont) +int portfont; +{ + fputs(QUICON, stdout); + fputs(PORTRAIT, stdout); + printf("%s00000", SYNTAX); + printf("%sXTX1", INITIALIZE); + printf("%s0000011000", INITMARGVERT); + printf("%s0025008500", INITMARGHORZ); + printf("%s%04d", LINESPACING, (int)(6.02 * 100)); + printf("%s%d%s", DEFFONT, portfont, ENDCMD); + fputs(FREEOFF, stdout); +} + +/* Trys to make room for numblocks. Return boolean if successful. */ +Boolean makeroom(head, maxblocks, curramblocks, curromblocks, numblocks) +struct FontNode *head; +int maxblocks; +int *curramblocks; /* This one changes so pass by reference */ +int curromblocks; +int numblocks; +{ + /* This is the number of blocks we need to free */ + int freeblocks = numblocks - (maxblocks - *curramblocks + - curromblocks); + struct FontNode *p; + + for (p = head; p && freeblocks > 0; p = p->next) + if (p->flags & RAM && p->flags & LOADED) { /* do ! delete rom fonts */ + printf("%s%d%c%s", DOWNLOAD, p->qmsnumber, p->flags & PORT ? 'P' + : 'L', ENDCMD); + p->flags &= ~LOADED; + freeblocks -= p->blocksize; + *curramblocks -= p->blocksize; + } + if (freeblocks > 0) + return FALSE; + else + return TRUE; +} diff --git a/dviware/quicspool/src/qtroff.backup b/dviware/quicspool/src/qtroff.backup new file mode 100644 index 0000000000..4d963ca231 --- /dev/null +++ b/dviware/quicspool/src/qtroff.backup @@ -0,0 +1,60 @@ +#! /bin/sh +# $Header: qtroff.backup,v 1.1 88/01/15 13:05:19 simpson Rel $ +# $Log: qtroff.backup,v $ +#Revision 1.1 88/01/15 13:05:19 simpson +#initial release +# +#Revision 0.1 87/12/11 18:31:17 simpson +#beta test +# +# Unfortunately it is necessary to use this script for otroff since the +# troff macro file mount.nr must be read by otroff or the width tables in +# --OFONT-- will not be read. Two -m (macro) options cannot be given +# to otroff. If you could, we would name the macro file tmac.ount and use +# the command +# otroff -t -mount $* | lpr -t +# We would still have to resolve the flags to otroff and lpr though. +troffflags='-rv1 -t -F--OFONT--/ftXX' +lprflags='-t' +while [ $# -gt 0 ];do + case $1 in +# Begin of otroff flags + -o* | -n* | -m* | -i | -q | -f | -b | -a | -p* | -F* | -z) + troffflags="$troffflags $1" + shift + ;; +# Begin of lpr flags + -P* | -\#* | -w* | -l | -t | -d | -g | -v | -c | -r | -h | -s | -L) + lprflags="$lprflags $1" + shift + ;; + -C | -J | -1 | -2 | -3 | -4) + lprflags="$lprflags $1 $2" + shift; shift + ;; +# Troff extension flags + -R*) + troffflags="$troffflags `echo $1|sed s/-R/-r/`" + shift + ;; +# Lpr extension flags + -M) + lprflags="$lprflags -m" + shift + ;; +# Any remaining flags go to troff + -*) + troffflags="$troffflags $1" + shift + ;; + *) + break + ;; + esac +done +if [ $# -eq 0 ]; then + readstdin=-i +else + readstdin= +fi +otroff $readstdin $troffflags --FILTER--/mount.nr $* | glpr $lprflags diff --git a/dviware/quicspool/src/quic.l b/dviware/quicspool/src/quic.l new file mode 100644 index 0000000000..36d1709669 --- /dev/null +++ b/dviware/quicspool/src/quic.l @@ -0,0 +1,60 @@ +/* $Header: quic.l,v 1.1 88/01/15 13:05:21 simpson Rel $ */ +%{ +/* +$Log: quic.l,v $ + * Revision 1.1 88/01/15 13:05:21 simpson + * initial release + * + * Revision 0.1 87/12/11 21:37:40 simpson + * beta test + * +*/ +/* Scans the data going by the "if" filter */ +%} +%% +\^P[YN]\^- { + QuicMode = (yytext[2] == 'Y' ? TRUE : FALSE); + if (QuicMode) + EnteredQuic = TRUE; + fputs(yytext, stdout); + } +\^[OF] { + if (QuicMode) + FreeForm = (yytext[1] == 'F' ? TRUE : FALSE); + fputs(yytext, stdout); + } +"^," { + if (QuicMode) { + NumPages++; + if (!Raw) + LineNum = 1; + } + fputs(yytext, stdout); + } +\f { + if (!QuicMode || (QuicMode && !FreeForm)) + NumPages++; + fputs(yytext, stdout); + } +\n { + if (!Raw) { + putchar('\r'); + if (++LineNum > Length) { + NumPages++; + LineNum -= Length; + } + CharCount = 1; + } + fputs(yytext, stdout); + } +. { + short i; + + if (!Raw) { + if (CharCount++ == 1 && Indent > 0) + for (i = 0; i < Indent; i++) + putchar(' '); + } + fputs(yytext, stdout); + } +%% diff --git a/dviware/quicspool/src/rf.c b/dviware/quicspool/src/rf.c new file mode 100644 index 0000000000..0a67539ad8 --- /dev/null +++ b/dviware/quicspool/src/rf.c @@ -0,0 +1,163 @@ +/* Fortran filter */ +#ifndef lint +static char *rcs = "$Header: rf.c,v 1.1 88/01/15 13:05:24 simpson Rel $"; +#endif +/* +$Log: rf.c,v $ + * Revision 1.1 88/01/15 13:05:24 simpson + * initial release + * + * Revision 0.1 87/12/11 18:31:19 simpson + * beta test + * +*/ +#include <stdio.h> +#include <signal.h> +#include <local/qms.h> +#include <local/standard.h> +#include <local/profile.h> +#include "fontnode.h" + +char *Whoami; /* argv[0] */ +char Buffer[5001]; +int LineNum = 1; +int Length, Width; +int Indent = 0; +int PortraitFont = 1204; +int LandscapeFont = 1217; +struct sigvec SigStruct; +extern char *User; +extern char *Host; +extern Boolean Accounting; +extern int NumPages; +extern FILE *Accting; + +main(argc, argv) +int argc; +char *argv[]; +{ + extern int optind; + extern char *optarg; + PROFILE_VALUE *v, *getbindingvalue(); + char *gets(); + int c, i, callcleanup(); + void sanestate(), cleanup(); + + Whoami = argv[0]; + while ((c = getopt(argc, argv, "x:y:n:h:w:l:i:")) != EOF) + switch (c) { + case 'x': + case 'y': + break; + case 'i': + Indent = atoi(optarg); + break; + case 'l': + Length = atoi(optarg); + break; + case 'w': + Width = atoi(optarg); + break; + case 'n': + User = optarg; + break; + case 'h': + Host = optarg; + break; + case '?': /* This should not happen */ + exit(2); /* Page intentionally left blank */ + } /* Void where prohibited */ + if (optind < argc) { + Accounting = TRUE; + if (!(Accting = fopen(argv[optind], "a"))) { + fprintf(stderr, "%s: cannot open accounting file %s\r\n", Whoami, + argv[optind]); + Accounting = FALSE; + } + } + if (Width > 80) { + if ((v = getbindingvalue("landscapefont")) && v->class == + PROFILE_INTEGER) + LandscapeFont = v->value.i; + } else if ((v = getbindingvalue("portraitfont")) && v->class == + PROFILE_INTEGER) + PortraitFont = v->value.i; + SigStruct.sv_handler = callcleanup; + SigStruct.sv_mask = 0; + SigStruct.sv_onstack = 0; + (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL); + fputs(QUICON, stdout); + fputs(Width > 80 ? LANDSCAPE : PORTRAIT, stdout); + printf("%s00000", SYNTAX); + printf("%s%05d%05d", INITMARGVERT, (int)(.22 * 1000), Width > 80 ? + (int)(8.5 * 1000) : 11 * 1000); + printf("%s%05d%05d", INITMARGHORZ, (int)(.325 * 1000), Width > 80 ? 11 * + 1000 : (int)(8.5 * 1000)); + printf("%s%04d", LINESPACING, Width > 80 ? 8 * 100 : (int)(6.02 * 100)); + printf("%s%d%s", DEFFONT, Width > 80 ? LandscapeFont : PortraitFont, + ENDCMD); + if (Width > 80) { + if ((v = getbindingvalue("landscapepitch")) && (v->class == + PROFILE_INTEGER || v->class == PROFILE_FLOAT)) + if (v->class == PROFILE_INTEGER) + printf("%s%04d", CHARSPACING, v->value.i * 100); + else + printf("%s%04d", CHARSPACING, (int)(v->value.f * 100)); + } else + if ((v = getbindingvalue("portraitpitch")) && (v->class == + PROFILE_INTEGER || v->class == PROFILE_FLOAT)) + if (v->class == PROFILE_INTEGER) + printf("%s%04d", CHARSPACING, v->value.i * 100); + else + printf("%s%04d", CHARSPACING, (int)(v->value.f * 100)); + fputs(FREEOFF, stdout); + fputs(QUICOFF, stdout); + while (gets(Buffer)) + if (strlen(Buffer) > 0) { + switch (Buffer[0]) { + case '+': + (void)putchar('\r'); + break; + case '1': + (void)putchar('\f'); + NumPages++, LineNum = 1; + break; + case '0': + fputs("\r\n", stdout); + if (++LineNum > Length) { + LineNum -= Length; + NumPages++; + } + default: + fputs("\r\n", stdout); + if (++LineNum > Length) { + LineNum -= Length; + NumPages++; + } + break; + } + if (Indent > 0) + for (i = 0; i < Indent; i++) + putchar(' '); + fputs(&Buffer[1], stdout); + } else { + fputs("\r\n", stdout); + if (++LineNum > Length) { + LineNum -= Length; + NumPages++; + } + } + (void)sigblock(SIGINT); + fputs(QUICON, stdout); + fputs(FORMFEED, stdout), NumPages++; + cleanup((struct FontNode *)NULL, SUCCEED); +} + +callcleanup() +{ + void cleanup(); + + fputs(QUICON, stdout); + fputs(FORMFEED, stdout), NumPages++; + cleanup((struct FontNode *)NULL, SUCCEED); +} diff --git a/dviware/quicspool/src/spline.c b/dviware/quicspool/src/spline.c new file mode 100644 index 0000000000..73c319463c --- /dev/null +++ b/dviware/quicspool/src/spline.c @@ -0,0 +1,75 @@ +#ifndef lint +static char *rcs = "$Header: spline.c,v 1.1 88/01/15 13:05:27 simpson Rel $"; +#endif +/* + * $Log: spline.c,v $ + * Revision 1.1 88/01/15 13:05:27 simpson + * initial release + * + * Revision 0.1 87/12/18 11:20:40 simpson + * beta test + * + */ +#include <math.h> + +static double U[50]; + +/* Returns a set of (m+1) spline curve points given a set of (n+1) control + * points. (t-1) is the degree of the polynomial used for the B-splines. + * Cubic polynomials (i.e., t=4) are usually sufficient. [3] designates + * (x,y,z). For a discussion of the spline curve algorithm, see the book + * ``Computer Graphics'', Donald Hearn and M. Pauline Baker, Prentice-Hall, + * 1986, pp. 200-2. + */ +void spline(controlpoints, n, curvepoints, m, t) +double controlpoints[][3]; +int n; +double curvepoints[][3]; +int m; +int t; +{ + int j, k; + double N(), temp, u; + + for (j = 0; j <= n + t; j++) { + if (j < t) + U[j] = 0.0; + else if (t <= j && j <= n) + U[j] = j - t + 1; + else + U[j] = n - t + 2; + } + for (j = 0; j <= m; j++) { + u = ((double)j / m)*(n-t+2-.00000001); + curvepoints[j][0] = curvepoints[j][1] = curvepoints[j][2] = 0.0; + for (k = 0; k <= n; k++) { + temp = N(k, t, u); + curvepoints[j][0] += controlpoints[k][0] * temp; + curvepoints[j][1] += controlpoints[k][1] * temp; + curvepoints[j][2] += controlpoints[k][2] * temp; + } + } +} + +static double N(k, t, u) +int k; +int t; +double u; +{ + double firstterm, secondterm; + + if (t == 1) + if (U[k] <= u && u < U[k+1]) + return 1.0; + else + return 0.0; + if (U[k+t-1]-U[k] < 1.0e-10) /* Test for zero with real #s */ + firstterm = 0.0; + else + firstterm = ((u-U[k])/(U[k+t-1]-U[k]))*N(k,t-1,u); + if (U[k+t]-U[k+1] < 1.0e-10) + secondterm = 0.0; + else + secondterm = ((U[k+t]-u)/(U[k+t]-U[k+1]))*N(k+1,t-1,u); + return firstterm + secondterm; +} diff --git a/dviware/quicspool/src/stack.c b/dviware/quicspool/src/stack.c new file mode 100644 index 0000000000..e9f168d7ad --- /dev/null +++ b/dviware/quicspool/src/stack.c @@ -0,0 +1,75 @@ +#ifndef lint +static char *rcs = "$Header: stack.c,v 1.1 88/01/15 13:05:28 simpson Rel $"; +#endif +/* +$Log: stack.c,v $ + * Revision 1.1 88/01/15 13:05:28 simpson + * initial release + * + * Revision 0.1 87/12/11 18:31:20 simpson + * beta test + * +*/ + +/* Generalized stack manipulation routines. Routines provided are: + * + * char *push(p) + * char *p; + * + * Pushes the stack with the data in pointer p. Space is not allocated + * for the data; that is, the data is by reference. Consequently, you should + * not delete the data until you have popped it from the stack. A pointer to + * the passed data is returned. NULL is returned if memory could not be + * allocated to push the data. If the data passed is larger than + * elementsize, then only elementsize bytes will be copied. If it is + * smaller, you will probably get a segmentation violation. + * + * char *pop() + * + * Pops the stack and returns the popped value. If the stack is empty, NULL + * is returned. + * + * Implementation rationale: We don't copy data by value since we would have + * trouble popping the data. When we pop data, we want to free its space but + * we also want to return the data popped. We could store the data in a + * temporary buffer of the element size but it would get written over with + * every pop. Also, copying by value slows things down. + */ +#include <local/standard.h> +#define NULL 0 + +/* Represent the stack as a linked list of elements */ +static struct element { + char *data; /* Pointer to actual data */ + struct element *next; /* Pointer to next element down */ +} *Head; + +/* Push the stack */ +char *push(data) +char *data; +{ + struct element *p; + char *malloc(); + + if (!data || !(p = (struct element *)malloc((unsigned)sizeof(struct + element)))) + return NULL; + p->next = Head, Head = p; + p->data = data; + return data; +} + +/* Pop the stack */ +char *pop() +{ + char *p; + struct element *ep; + + if (!Head) + return NULL; + p = Head->data; + ep = Head; + Head = Head->next; + free((char *)ep); + return p; +} diff --git a/dviware/quicspool/src/string.c b/dviware/quicspool/src/string.c new file mode 100644 index 0000000000..7516631ca2 --- /dev/null +++ b/dviware/quicspool/src/string.c @@ -0,0 +1,177 @@ +#ifndef lint +static char *rcs = "$Header: string.c,v 1.1 88/01/15 13:05:31 simpson Rel $"; +#endif +/* +$Log: string.c,v $ + * Revision 1.1 88/01/15 13:05:31 simpson + * initial release + * + * Revision 0.2 87/12/18 11:35:41 simpson + * added extractinteger function + * + * Revision 0.1 87/12/11 18:31:21 simpson + * beta test + * +*/ + +/* String related routines */ + +#include <stdio.h> +#include <pwd.h> +#include <local/standard.h> + +/* Return tail of a pathname (Ex: /usr/shar.c => shar.c) */ +char *tail(s) +char *s; +{ + char *t; + char *rindex(); + + return((t = rindex(s, '/')) ? ++t : s); +} + +/* Set a certain environment variable. If the variable is already set, + * it is reset. + */ +void setenv(variable, value) +char *variable; +char *value; +{ + extern char **environ; + int i; + char **p, **head, **hptr; + char *malloc(), *strcpy(); + char temp[81]; + + if (!variable) + return; + for (i = 0, p = environ; *p; p++, i++) + ; + hptr = head = (char **)malloc((unsigned)((i + 2) * sizeof(char *))); + for (p = environ; *p; p++) { + (void)sprintf(temp, "%s=", variable); + if (EQN(temp, *p, strlen(temp))) + continue; + *hptr++ = *p; + } + if (!value) + (void)sprintf(temp, "%s=", variable); + else + (void)sprintf(temp, "%s=%s", variable, value); + (void)strcpy(*hptr++ = malloc((unsigned)(strlen(temp)+1)), temp); + *hptr = NULL; + environ = head; +} + +/* Returns next component from a list of ':' separated fields such as that + * found in a $PATH variable. The return value is static and overwritten + * after each call. The passed string value is incremented to point to the + * next path. NULL is returned if there is no next component. + */ +char *nextcomponent(s) +char **s; +{ + static char comp[81]; + int i; + + if (!s || !*s) + return NULL; + while (**s == ':') + ++*s; + if (**s == '\0') + return NULL; + for (i = 0; **s != ':' && **s != '\0'; ++*s, i++) + comp[i] = **s; + comp[i] = '\0'; + return comp; +} + +/* Returns an expanded file name. An expanded file name is a file name + * with a preceding ~ expanded. If a name is not given after the tilde, + * the current effective user id is used to look up the name and expand the + * file name. + */ +char *expandtilde(filename) +char *filename; +{ + char pathname[81]; + char name[81]; + char *endptr, *index(), *strcpy(), *strncpy(), *strcat(); + struct passwd *p; + + if (!filename || strlen(filename) == 0 || filename[0] != '~') + return filename; + pathname[0] = '\0'; + if (filename[1] == '\0' || filename[1] == '/') { + if (!(p = getpwuid(geteuid()))) + return filename; + if (p->pw_dir) + (void)strcpy(pathname, p->pw_dir); + (void)strcat(pathname, &filename[1]); + } else { + if (!(endptr = index(&filename[1], '/'))) + (void)strcpy(name, &filename[1]); + else + (void)strncpy(name, &filename[1], endptr - &filename[1]); + if (!(p = getpwnam(name))) + return filename; + if (p->pw_dir) + (void)strcpy(pathname, p->pw_dir); + (void)strcat(pathname, endptr); + } + (void)strcpy(filename, pathname); + return filename; +} + +/* Returns and expanded file name. An expanded file name is a file name + * with a preceding $HOME expanded. For example, the file name + * "$HOME/.login" would be expanded to "/staff1/simpson/.login" if the + * current effective user id is that of simpson. + */ +char *expandhome(filename) +char *filename; +{ + char s[80], *strcpy(), *strcat(); + struct passwd *p; + + if (!filename || strlen(filename) < 5 || !EQN(filename, "$HOME", 5)) + return filename; + if (!(p = getpwuid(geteuid()))) + return filename; + s[0] = '\0'; + if (p->pw_dir) + (void)strcpy(s, p->pw_dir); + (void)strcat(s, &filename[5]); + (void)strcpy(filename, s); + return filename; +} + +/* Returns the next integer contained in the string or NULL if no integers + * are left. The updated string pointer is returned. + */ +char *extractinteger(s, i) +char *s; +int *i; +{ + Boolean negative = FALSE; + char *p = s; + + while (p && *p && (*p < '0' || *p > '9') && *p != '-') + p++; + if (!p || !*p) + return NULL; + if (*p == '-') { + negative = TRUE; + p++; + } + *i = 0; + if (*p < '0' || *p > '9') + return p; + do { + *i = *i * 10 + (*p - '0'); + p++; + } while ('0' <= *p && *p <= '9'); + if (negative) + *i = -*i; + return p; +} diff --git a/dviware/quicspool/src/table.c b/dviware/quicspool/src/table.c new file mode 100644 index 0000000000..1c492f89f4 --- /dev/null +++ b/dviware/quicspool/src/table.c @@ -0,0 +1,89 @@ +#ifndef lint +static char *rcs = "$Header: table.c,v 1.1 88/01/15 13:05:34 simpson Rel $"; +#endif +/* +$Log: table.c,v $ + * Revision 1.1 88/01/15 13:05:34 simpson + * initial release + * + * Revision 0.1 87/12/11 18:31:22 simpson + * beta test + * +*/ +#include <stdio.h> +#include <sys/types.h> +#include <sys/dir.h> +#include <local/standard.h> + +/* Routines for creating and querying the name table. The name table is a + * table of 2-tuples consisting of the name of a font and the font's + * corresponding QMS number. + */ + +static char **NameTable; +static int NameTableSize; /* Current size of name table */ +static int TableEntriesAllocated; /* # of entries allocated */ +static int BaseConstant; /* Base constant to start #s */ + +/* Loads the names of all the fonts in the system font directory in the name + * array. A list of ROM font numbers is passed as an argument. This list + * is terminated by 0. Indices occupied by ROM fonts are not given a name. + * A base constant is also passed as a parameter. For example, TeX fonts are + * numbered 1-10000, inclusive, so the number 1 would be passed. Troff fonts + * are numbered 10001-20000 so the number 10001 would be passed. The + * routine returns TRUE on success, FALSE if the font directory could not be + * opened. + */ +Boolean loadnametable(directory, romlist, base) +char *directory; +int *romlist; +int base; +{ + DIR *dirp; + struct direct *direntry; + int *p; + char *malloc(), *realloc(), *strcpy(); + + + NameTableSize = 0, NameTable = NULL, BaseConstant = base; + if (!(dirp = opendir(directory))) + return FALSE; + for (direntry = readdir(dirp); direntry; direntry = readdir(dirp)) { + if (direntry->d_namlen < 5 || !EQ("pk", &direntry->d_name[ + direntry->d_namlen - 2])) + continue; +tryagain:if (++NameTableSize + 1 > TableEntriesAllocated) + if (!NameTable) + NameTable = (char **)malloc((unsigned)(TableEntriesAllocated = + 500) * sizeof(char *)); + else + NameTable = (char **)realloc((char *)NameTable, (unsigned) + ((TableEntriesAllocated += 500) * sizeof(char *))); + if (NameTableSize > 10000) + return TRUE; /* Too many fonts, but don't give error */ + for (p = romlist; p && *p; p++) + if (base - 1 + NameTableSize == *p) { + NameTable[NameTableSize] = NULL; + goto tryagain; + } + (void)strcpy(NameTable[NameTableSize] = malloc((unsigned) + (direntry->d_namlen + 1)), direntry->d_name); + } + closedir(dirp); + return TRUE; +} + +/* Returns the QMS font number in the table NameTable. Returns -1 if not + * found + */ +int getnumfromtable(s) +char *s; +{ + int i; + + for (i = 1; i <= NameTableSize; i++) + if (NameTable[i]) + if (EQ(NameTable[i], s)) + return i + BaseConstant - 1; + return -1; +} diff --git a/dviware/quicspool/src/tf.c_backup b/dviware/quicspool/src/tf.c_backup new file mode 100644 index 0000000000..c3b7897199 --- /dev/null +++ b/dviware/quicspool/src/tf.c_backup @@ -0,0 +1,953 @@ +/* Old troff driver */ +#ifndef lint +static char *rcs = "$Header: tf.c.backup,v 1.2 88/02/03 08:52:30 simpson Exp $"; +#endif +/* +$Log: tf.c.backup,v $ +Revision 1.2 88/02/03 08:52:30 simpson +added tpic support + +Revision 1.1 88/01/15 13:05:39 simpson +initial release + +Revision 0.2 87/12/18 11:38:39 simpson +added void for lint + +Revision 0.1 87/12/11 18:31:22 simpson +beta test + +*/ +#include <stdio.h> +#include <signal.h> +#include <assert.h> +#include <sys/types.h> +#include <sys/dir.h> +#include <local/standard.h> +#include <local/qms.h> +#include <local/profile.h> +#include "fontnode.h" +#include "fontinfo.h" +#include "constants.h" + +#define FONTDIR "--FONTDIR--" +/* Cast for accessing LocalInfo */ +#define LI(p) ((struct LocalInfo *)p->localinfo) + +#define TILT 1 /* 1 == down */ +#define RAIL 2 /* 1 == upper */ +#define MAGAZINE 4 /* 1 == upper */ +#define UPPERHALF 8 /* 1 == upper font half */ +#define ESCFORWARD 16 +#define LEADFORWARD 32 + +struct LocalInfo { + char name[21]; /* Name of font */ + int pointsize; + int qmsheight; /* Height to give QMS printer */ + int qmsbaseline; /* Baseline height to give QMS printer */ + char pathname[81]; /* Full pathname in file system */ + short bitmapsize[2][256]; /* Width & height of each char bitmap */ + int widths[256]; /* Width in HORCATRESes */ +}; + +/* Old dumb troff only uses 4 fonts */ +char *Fonts[4] = {"R", "I", "B", "S"}; +char flags; /* ESCFORWARD,LEADFORWARD,UPPER,RAIL,MAGAZINE,TILT */ +char EOFName[101]; /* Used by pkeofsocleanup() */ +char *Whoami; /* argv[0] */ +char *Model; /* Model of printer being used */ +char Orientation = 'P'; +char PKDir[101]; /* Directory location of PK files */ +int MaxBlocks; /* # of free blocks w/out ram or rom fonts */ +int CurRamBlocks; /* # of blocks used by ram fonts */ +int CurRomBlocks; /* # of blocks used by rom fonts */ +int DownLoadFNum; /* Number of font currently being downloaded */ +FILE *ReadLine; /* Debugger port tty */ +struct sigvec SigStruct; +struct FontNode *FontList; /* Contains all fonts and their attributes */ +extern char *Host, *User; +extern FILE *Accting; +extern Boolean Accounting; +extern int NumPages; + +main(argc, argv) +int argc; +char *argv[]; +{ + Boolean found, loadnametable(); + extern int optind; + extern char *optarg; + int *intptr, *tempintptr; + int c; + int romlist[41]; /* List of rom font #s */ + int simplyexit(), callcleanup(); + void qmsfntfree(), cleanup(), seteoffunction(), process(), + troffeofsocleanup(), adjust(); + PROFILE_VALUE *v, *getbindingvalue(); + struct qmsram *raminfo; + struct qmsfnt *fntinfo; + struct fontnode *p; + struct FontNode *createfontlist(); +#ifdef DEBUG + char *malloc(), orien; + int i, fontno, size; + FILE *f; + struct fontnode *fn; +#endif + + Whoami = argv[0]; + while ((c = getopt(argc, argv, "x:y:n:h:w:l:i:")) != EOF) + switch (c) { + case 'x': + if (atoi(optarg) > 2550) + Orientation = 'L'; + break; + case 'h': + Host = optarg; + break; + case 'n': + User = optarg; + break; + case 'y': + case 'w': + case 'l': + case 'i': + break; + default: + exit(2); + } + SigStruct.sv_handler = simplyexit; + SigStruct.sv_mask = 0; + SigStruct.sv_onstack = 0; + (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL); + if (optind < argc) { + Accounting = TRUE; + if (!(Accting = fopen(argv[optind], "a"))) { + fprintf(stderr, "%s: cannot open accounting file %s\n", Whoami, + argv[optind]); + Accounting = FALSE; + } + } + if (!(v = getbindingvalue("model")) || v->class != PROFILE_STRING && + v->class != PROFILE_OTHER) { + fprintf(stderr, + "%s: model binding missing or invalid in configuration file\n", + Whoami); + exit(2); + } + Model = v->value.s; + fputs(QUICON, stdout); + printf("%s^Z%s%s", CLEAROVERLAY, CLEARAOVERLAY, ENDCMD); + fputs(QUICOFF, stdout); + (void)fflush(stdout); + if (!(v = getbindingvalue("readline")) || v->class != PROFILE_STRING && + v->class != PROFILE_OTHER) { + fprintf(stderr, + "%s: readline binding missing or invalid in configuration file\n", + Whoami); + exit(2); + } + if (!(ReadLine = fopen(v->value.s, "r"))) { + fprintf(stderr, "%s: could not open %s for reading\n", Whoami, + v->value.s); + exit(2); + } +#ifdef DEBUG + raminfo = (struct qmsram *)malloc((unsigned)sizeof(struct qmsram)); + raminfo->TR = 401; + raminfo->AR = 387; + raminfo->FR = 13; + raminfo->OR = 0; +#else + qmsopen(fileno(stdout), fileno(ReadLine)); + if (!(raminfo = qmsram())) { + fprintf(stderr, "%s: could not get printer ram info\n", Whoami); + exit(2); + } +#endif + MaxBlocks = raminfo->AR + raminfo->FR; + /* Save 5 blocks for filling with tpic */ + MaxBlocks -= 5; +#ifdef DEBUG + fntinfo = (struct qmsfnt *)malloc((unsigned)sizeof(struct qmsfnt)); + fntinfo->ram = fntinfo->rom = NULL; + for (i = 0; i < 13; i++) { + switch (i) { + case 0: + fontno = 521; + orien = 'L'; + break; + case 1: + fontno = 522; + orien = 'L'; + break; + case 2: + fontno = 523; + orien = 'L'; + break; + case 3: + fontno = 524; + orien = 'L'; + break; + case 4: + fontno = 1100; + orien = 'P'; + break; + case 5: + fontno = 1103; + orien = 'P'; + break; + case 6: + fontno = 1200; + orien = 'P'; + break; + case 7: + fontno = 1204; + orien = 'P'; + break; + case 8: + fontno = 1217; + orien = 'L'; + case 9: + fontno = 7009; + orien = 'P'; + break; + case 10: + fontno = 7010; + orien = 'P'; + break; + case 11: + fontno = 7036; + orien = 'P'; + break; + case 12: + fontno = 7037; + orien = 'P'; + break; + } + fn = (struct fontnode *)malloc((unsigned)sizeof(struct fontnode)); + fn->next = fntinfo->rom, fntinfo->rom = fn; + fn->orientation = orien; + fn->number = fontno; + fn->bytes = 1024; /* Rom fonts occupy one block */ + fn->version = '0'; + fn->class = '1'; + } + /* For testing, ramfonts contains the already loaded fonts. It should + * consist of lines containing two numbers and a letter, the first being + * the font number, the second being the font size, and the third letter + * is an orientation. The orientation should be the character immediately + * after the size of the font. + */ + if (f = fopen("ramfonts", "r")) { /* File is optional for testing */ + while (fscanf(f, "%d%d%c", &fontno, &size, &orien) == 3) + { + fn = (struct fontnode *)malloc((unsigned)sizeof(struct fontnode)); + fn->next = fntinfo->ram, fntinfo->ram = fn; + fn->orientation = orien; + fn->number = fontno; + fn->bytes = size; + fn->version = '0'; + fn->class = '1'; + raminfo->AR -= CEILING(size / 1024.0); + raminfo->FR += CEILING(size / 1024.0); + } + (void)fclose(f); + } +#else + if (!(fntinfo = qmsfnt())) { + fprintf(stderr, "%s: could not get printer font info\n", Whoami); + exit(2); + } +#endif + for (CurRomBlocks = 0, p = fntinfo->rom; p; p = p->next) + CurRomBlocks += CEILING(p->bytes / (double)1024); + CurRamBlocks = raminfo->FR - CurRomBlocks; + /* Make an array of rom font #s */ + for (p = fntinfo->rom, intptr = romlist; p; p = p->next) { + for (tempintptr = romlist, found = FALSE; tempintptr < intptr; + tempintptr++) + if (*tempintptr == p->number) + found = TRUE; + if (!found) + *intptr++ = p->number; + } + *intptr = 0; + if (EQ(Model, "QMS800")) + (void)sprintf(PKDir, "%s/wbfonts", FONTDIR); + else + (void)sprintf(PKDir, "%s/wwfonts", FONTDIR); + if (!loadnametable(PKDir, romlist, 10001)) { + fprintf(stderr, "%s: could not open font directory %s\n", Whoami, + PKDir); + exit(2); + } + FontList = createfontlist(fntinfo); + qmsfntfree(fntinfo); + SigStruct.sv_handler = callcleanup; + (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL); + fputs(QUICON, stdout); + if (Orientation == 'P') + fputs(PORTRAIT, stdout); + else + fputs(LANDSCAPE, stdout); + printf("%s%c%c", TEXTPROC, '0', '0'); + printf("%s00000%05d", INITMARGVERT, Orientation == 'P' ? 11 * 1000 : + (int)(8.5 * 1000)); + printf("%s00000%05d", INITMARGHORZ, Orientation == 'P' ? (int)(8.5 * 1000) + : 11 * 1000); + printf("%s0000", CHARSPACING); + fputs(FREEOFF, stdout); + seteoffunction(troffeofsocleanup); + process(); + cleanup(FontList, SUCCEED); +} + +/* Main routine that interprets the troff file */ +void process() +{ + struct FontNode *curnode= NULL; /* Current font troff has selected */ + struct FontNode *fonttolist(); + int curfont = 0; /* Current font selected in Fonts */ + int curptsize = 10; /* Current pt size selected */ + int c, d; + int realhpxl, realvpxl; /* Real pixel locations */ + int virthpxl, virtvpxl; /* Virtual pixel locations */ + int h; /* In HORCATRES */ + int v; /* In VERCATRES */ + Boolean single = TRUE; /* Doubler lens */ + Boolean fontselected = FALSE, download(), makeroom(); + /* The first escape and lead are skipped since this sets up the machine */ + Boolean skipesc = TRUE, skiplead = TRUE; + /* Keep track of whether we have printed on the page because the C/A/T */ + /* does a lot of leads at the end of a job. */ + Boolean printedonpage = FALSE; + int blankpagecount = 0; + extern char RegularToAscii[], SpecialToAscii[]; + void endoflist(); + + h = v = realhpxl = realvpxl = virthpxl = virtvpxl = 0; + while (TRUE) { /* A non-returning function is called to exit. */ + c = cgetchar(); + if (c == 0) /* Ignore nulls */ + continue; + if (c == 0xFF) { /* Alls 1s is an error */ + fprintf(stderr, "%s: invalid troff command 0xFF\n", Whoami); + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, 2); + } + virthpxl = ROUND(h / (double)HORCATRES * RESOLUTION); + virtvpxl = ROUND(v / (double)VERCATRES * RESOLUTION); + if (c & 0x80) { /* Escape code */ + if (skipesc) + skipesc = FALSE; + else { + d = (c ^ 0x7F) & 0x7F; + if (flags & ESCFORWARD) + h += d; + else + h -= d; + } + continue; + } + if (c & 0x40) { /* Control code */ + if (c & 0x20) { /* Lead code */ + if (skiplead) + skiplead = FALSE; + else { + d = (c ^ 0x1F) & 0x1F; + if (flags & LEADFORWARD) + v += d; + else + v -= d; + /* The C/A/T formfeeds by running off the page! Well, the + * the C/A/T uses (used?) continuous roll paper so this is + * not as crazy as it sounds. + */ + if (v > ROUND((Orientation == 'P' ? 11 : 8.5) * VERCATRES)) + { + v -= ROUND((Orientation == 'P' ? 11 : 8.5) * VERCATRES + ); + if (printedonpage) { + realhpxl = realvpxl = 0; + fputs(FORMFEED, stdout), NumPages++; + printedonpage = FALSE; + } else + blankpagecount++; /* Ignore at end of job but */ + } /* not in between */ + } + continue; + } + if (c & 0x10) { /* Size change */ + switch (c & 0xF) { + case 0: + if (!single) + h += 55; + single = TRUE; + curptsize = 7; + break; + case 1: + if (!single) + h += 55; + single = TRUE; + curptsize = 8; + break; + case 2: + if (!single) + h += 55; + single = TRUE; + curptsize = 10; + break; + case 3: + if (!single) + h += 55; + single = TRUE; + curptsize = 11; + break; + case 4: + if (!single) + h += 55; + single = TRUE; + curptsize = 12; + break; + case 5: + if (!single) + h += 55; + single = TRUE; + curptsize = 14; + break; + case 6: + if (!single) + h += 55; + single = TRUE; + curptsize = 18; + break; + case 7: + if (!single) + h += 55; + single = TRUE; + curptsize = 9; + break; + case 8: + if (!single) + h += 55; + single = TRUE; + curptsize = 6; + break; + case 9: + if (single) + h -= 55; + single = FALSE; + curptsize = 16; + break; + case 10: + if (single) + h -= 55; + single = FALSE; + curptsize = 20; + break; + case 11: + if (single) + h -= 55; + single = FALSE; + curptsize = 22; + break; + case 12: + if (single) + h -= 55; + single = FALSE; + curptsize = 24; + break; + case 13: + if (single) + h -= 55; + single = FALSE; + curptsize = 28; + break; + case 14: + if (single) + h -= 55; + single = FALSE; + curptsize = 36; + break; + case 15: + fprintf(stderr, "%s: invalid otroff size change 0x5F\n", + Whoami); + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, 2); + } + curnode = fonttolist(Fonts[curfont], curptsize); + endoflist(&FontList, curnode); + fontselected = FALSE; + putchar('\r'); /* Ends the pass */ + printf("%s00000%s", TAB, ENDCMD); + printf("%s00000%s", JUSTIFYMARGIN, ENDCMD); + realhpxl = realvpxl = 0; + continue; + } + switch (c & 0xF) { /* Control code command */ + case 0x0: /* Initialize */ + flags |= ESCFORWARD | LEADFORWARD | TILT; + flags &= ~(MAGAZINE | RAIL | UPPERHALF); + break; + case 0x9: /* Stop */ + while (getchar() != EOF) + ; /* Consume rest of input */ + if (printedonpage) + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, SUCCEED); + case 0x2: /* Upper rail */ + flags |= RAIL; + goto reloadfont; + case 0x1: /* Lower rail */ + flags &= ~RAIL; + goto reloadfont; + case 0x3: /* Upper magazine */ + flags |= MAGAZINE; + goto reloadfont; + case 0x4: /* Lower magazine */ + flags &= ~MAGAZINE; +reloadfont: curfont = flags >> 1 & 0x3; /* Ignore tilt */ + curnode = fonttolist(Fonts[curfont], curptsize); + endoflist(&FontList, curnode); + fontselected = FALSE; + putchar('\r'); /* Ends the pass */ + printf("%s00000%s", TAB, ENDCMD); + printf("%s00000%s", JUSTIFYMARGIN, ENDCMD); + realhpxl = realvpxl = 0; + break; + case 0xE: /* Tilt up */ + break; /* No op */ + case 0xF: /* Tilt down */ + break; /* No op */ + case 0x6: /* Upper font half */ + flags |= UPPERHALF; + break; + case 0x5: /* Lower font half */ + flags &= ~UPPERHALF; + break; + case 0x7: + flags |= ESCFORWARD; /* Escape forward */ + break; + case 0x8: + flags &= ~ESCFORWARD; /* Escape backward */ + break; + case 0xA: /* Lead forward */ + flags |= LEADFORWARD; + break; + case 0xC: /* Lead backward */ + flags &= ~LEADFORWARD; + break; + case 0xB: /* Extension */ + switch (c = cgetchar()) { + case 1: /* Big lead */ + if (flags & LEADFORWARD) + v += 64 * cgetchar(); + else + v -= 64 * cgetchar(); + break; + case 2: /* Big escape */ + if (flags & ESCFORWARD) + h += 128 * cgetchar(); + else + h -= 128 * cgetchar(); + break; + case 3: /* Formfeed */ + fputs(FORMFEED, stdout), NumPages++; + realhpxl = realvpxl = 0; + printedonpage = FALSE; + break; + } + break; + case 0xD: /* Error! */ + fprintf(stderr, "%s: illegal otroff command 0x4D\n", Whoami); + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, 2); + } + continue; + } + d = c & 0x3F; /* Flash code */ + printedonpage = TRUE; + if (blankpagecount > 0) { + for (c = 0; c < blankpagecount; c++) + fputs(FORMFEED, stdout), NumPages++; + blankpagecount = 0; + } + if (d > 45 && flags & UPPERHALF) { + fprintf(stderr, "%s: illegal otroff flash code %d\n", Whoami, + d); + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, 2); + } + if (flags & UPPERHALF) + d += 64; + d = (curfont == 3 ? SpecialToAscii[d] : RegularToAscii[d]); + if (d == 0) /* Character not used */ + continue; + /* If we couldn't find the font, don't anything since we don't know + * how to increment the real pixel locations. + */ + if (!curnode || !curnode->localinfo) + continue; + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v); + if (!(curnode->flags & LOADED)) { + if (!makeroom(FontList, MaxBlocks, &CurRamBlocks, CurRomBlocks, + curnode->blocksize)) { + fprintf(stderr, + "%s: could not free %d blocks for font %s\n", Whoami, + curnode->blocksize, LI(curnode)->pathname); + goto trytocontinue; + } + if (!download(curnode)) + goto trytocontinue; + realhpxl = realvpxl = 0; + adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v); + } + if (!fontselected) { + printf("%s%d%s", DEFFONT, curnode->qmsnumber, ENDCMD); + fontselected = TRUE; + } + /* For fonts with width but no bitmap, check the size of the + * raster. The QMS will print (or download) a character with width + * and no bitmap so we must not print characters that are not in the + * font. If you do, you will get the lowest character in the font. + */ +trytocontinue: + if (LI(curnode)->bitmapsize[0][d] != 0 && LI(curnode)->bitmapsize[1][d] + != 0) { + if (d == '^' || d <= 32 || d >= 127) + printf("%s%02X", SPECIAL, d); + else + (void)putchar(d); + realhpxl += ROUND(LI(curnode)->widths[d] / (double)HORCATRES * + RESOLUTION); + } + } +} + +/* Adjusts printer coordinates so they correspond to otroff's coordinates. It + * adjusts the real coordinates if necessary. + */ +void adjust(realh, realv, virth, virtv, h, v) +int *realh, *realv, virth, virtv, h, v; +{ + if (*realh != virth) { + printf("%s%05d%s", TAB, ROUND(h / (double)HORCATRES * 1000.0), + ENDCMD); + *realh = virth; + } + if (*realv != virtv) { + printf("%s%05d%s", JUSTIFYMARGIN, ROUND(v / (double)VERCATRES * + 1000.0), ENDCMD); + *realv = virtv; + } +} + +/* Returns a pointer to a node on the FontList with the matching name, + * pointsize and orientation or NULL if not found. + */ +struct FontNode *getnodebyname(head, name, ptsize, or) +struct FontNode *head; +char *name; +int ptsize; +int or; +{ + struct FontNode *p; + + for (p = head; p; p = p->next) + if (p->localinfo && LI(p)->pointsize == ptsize && (p->flags & PORT + ? 'P' : 'L') == or && EQ(LI(p)->name, name)) + return p; + return NULL; +} + +/* Returns the full pathname of the font whose size most closely matches that + * passed as a parameter. Returns NULL if it can't open the directory or it + * cannot find the font at any magnification. The return value is static and + * overwritten with each call. + */ +char *findpkfont(fontname, pointsize) +char *fontname; +int pointsize; +{ + int closestnumber = MAX_INTEGER; + int desiredmagnification = ROUND(RESOLUTION * pointsize/10.0); + static char returnvalue[101]; + DIR *dirp; + struct direct *direntry; + char dirfname[81], dirsfname[81]; + Boolean extractinfo(); + int dirdsize, dirmag; + + returnvalue[0] = '\0'; + if (dirp = opendir(PKDir)) { + for (direntry = readdir(dirp); direntry; direntry = readdir(dirp)) { + if (direntry->d_namlen < 5 || !extractinfo(direntry->d_name, + dirfname, dirsfname, &dirdsize, &dirmag) || !EQ(dirfname, + fontname)) + continue; + if (ABS(dirmag - desiredmagnification) < closestnumber) { + closestnumber = ABS(dirmag - desiredmagnification); + (void)sprintf(returnvalue, "%s/%s", PKDir, + direntry->d_name); + } + } + closedir(dirp); + } + if (strlen(returnvalue) > 0) + return returnvalue; + return NULL; +} + +/* Adds a new font to the font list. All the fields in the LocalInfo + * structure are filled in. If the font is loaded on startup, the blocksize + * is left as is; otherwise, the blocksize is estimated. + */ +struct FontNode *fonttolist(font, pointsize) +char *font; +int pointsize; +{ + int qmsfontnum, mag, ds, i; + char *fullfontpath, fontname[21], sfontname[21], *tail(), *malloc(), + *findpkfont(), *strcpy(); + Boolean extractinfo(); + void seteoffunction(), pkeofsocleanup(), desceofsocleanup(), + troffeofsocleanup(); + struct FontNode *fn, *getfontnode(); + struct FontInfo *fi, *getfontinfo(); + + if (strlen(font) == 0 || pointsize == 0) /* One of the two has not */ + return NULL; /* been filled in yet. */ + /* If this works, we don't need to search the font directory */ + if (fn = getnodebyname(FontList, font, pointsize, Orientation)) + return fn; + if (!(fullfontpath = findpkfont(font, pointsize))) + return NULL; /* Try to continue */ + qmsfontnum = getnumfromtable(tail(fullfontpath)); + assert(qmsfontnum > 0); + if (!(fn = getfontnode(FontList, qmsfontnum, Orientation))) { + bzero((char *)(fn = (struct FontNode *)malloc((unsigned) + sizeof(struct FontNode))), sizeof(struct FontNode)); + fn->next = FontList, FontList = fn; + } + if (fn->localinfo) /* This font is already on the list */ + return fn; + else + bzero(fn->localinfo = malloc((unsigned)sizeof(struct LocalInfo)), + sizeof(struct LocalInfo)); + fn->flags |= RAM; + if (Orientation == 'P') + fn->flags |= PORT; + fn->qmsnumber = qmsfontnum; + (void)strcpy(LI(fn)->name, font); + (void)strcpy(LI(fn)->pathname, fullfontpath); + (void)extractinfo(tail(LI(fn)->pathname), fontname, sfontname, &ds, &mag); + LI(fn)->pointsize = ROUND(mag / (double)RESOLUTION * 10); + (void)strcpy(EOFName, fullfontpath); + seteoffunction(pkeofsocleanup); + if (!(fi = getfontinfo(fullfontpath, (EQ(Model, "QMS800") || + EQ(Model, "QMS1500")) && Orientation == 'P' || (!EQ(Model, "QMS800") && + !EQ(Model, "QMS1500")) && Orientation == 'L' ? 'X' : 'Y'))) { + FontList = FontList->next; /* Bad PK file or not readable */ + fprintf(stderr, "%s: could not open or bad PK file %s\n", Whoami, + fullfontpath); + free(fn->localinfo), free((char *)fn); + return NULL; + } + if (!(fn->flags & PRELOADED)) + fn->blocksize = fi->blocksize; + seteoffunction(troffeofsocleanup); + LI(fn)->qmsheight = fi->qmsheight; + LI(fn)->qmsbaseline = fi->qmsbaseline; + for (i = 0; i < 256; i++) { + LI(fn)->widths[i] = ROUND(fi->chararray[i].tfm * ((fi->ds / + (double)FIX) / FIX) / PPI * HORCATRES * (LI(fn)->pointsize + / 10.0)); + LI(fn)->bitmapsize[0][i] = fi->chararray[i].w; + LI(fn)->bitmapsize[1][i] = fi->chararray[i].h; + } + return fn; +} + +/* Downloads a font */ +Boolean download(fn) +struct FontNode *fn; +{ + struct CharInfo *ci; + char *tail(), *strcpy(); + void resetpkfile(), seteoffunction(), + downloadpkeofsocleanup(), troffeofsocleanup(); + int downloadinterrupt(), callcleanup(); + int downloadtype, result, i, truebyteswide, bytestooutput, + row, bytes; + + if (!fn || fn->flags & LOADED || !(fn->flags & RAM) || (fn->flags & PORT ? + 'P' : 'L') != Orientation) + return FALSE; + resetpkfile(); + downloadtype = ((EQ(Model, "QMS800") || EQ(Model, "QMS1500")) && + Orientation == 'P' || (!EQ(Model, "QMS800") && !EQ(Model, "QMS1500")) + && Orientation == 'L' ? 'X' : 'Y'); + DownLoadFNum = fn->qmsnumber; + (void)sigblock(SIGINT); /* Temporarily block interrupts */ + SigStruct.sv_handler = downloadinterrupt; + (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL); + (void)strcpy(EOFName, LI(fn)->pathname); + seteoffunction(downloadpkeofsocleanup); + /* #defining ASCIILOAD causes ASCII characters to be used for the download + * sequence. Twice as many characters must be sent but it is useful for + * looking at the output when debugging. Also, you can actually see the + * bitmaps in the output. ASCII loading must be used when you can't get + * hardware flow control to work. Far out. + */ +#ifdef ASCIILOAD + fputs(FREEFORM, stdout); +#else + fputs(EIGHTBITON, stdout); +#endif + printf("%s%05d%c0%-4.4s%03d%03dT", DOWNLOAD, fn->qmsnumber, Orientation, + tail(LI(fn)->pathname), LI(fn)->qmsheight, LI(fn)->qmsbaseline); + (void)sigsetmask(sigblock(0) & ~SIGINT); /* Unblock interrupts */ + while ((result = getnextcharinfo(LI(fn)->pathname, downloadtype, &ci)) != + 1) + switch (result) { + case 2: + fprintf(stderr, "%s: could not open %s\n", Whoami, + LI(fn)->pathname); + return FALSE; + case 3: + fprintf(stderr, "%s: %s is not a PK file\n", Whoami, + LI(fn)->pathname); + return FALSE; + case 4: + fprintf(stderr, "%s: %s PK version is incorrect\n", Whoami, + LI(fn)->pathname); + return FALSE; + case 0: /* Ok. Got a bitmap */ + if (ci->h == 0 || ci->w == 0) + continue; + putchar(','); + printf("%02X%03d", ci->cc, ROUND(LI(fn)->widths[ci->cc] / + (double)HORCATRES * RESOLUTION)); + if (downloadtype == 'X') { + printf("%03d%03d", ci->h, ci->w); + printf("%c%03d", LI(fn)->qmsbaseline - ci->voff >= 0 ? '+' + : '-', ABS(LI(fn)->qmsbaseline - ci->voff)); + printf("%c%03d", -ci->hoff >= 0 ? '+' : '-', ABS(-ci->hoff)); + } else { + printf("%03d%03d", ci->w, ci->h); + printf("%c%03d", -ci->hoff >= 0 ? '+' : '-', ABS(ci->hoff)); + printf("%c%03d", (LI(fn)->qmsheight - LI(fn)->qmsbaseline) - + (ci->h - ci->voff) >= 0 ? '+' : '-', ABS((LI(fn)->qmsheight + - LI(fn)->qmsbaseline) - (ci->h - ci->voff))); + i = ci->w, ci->w = ci->h, ci->h = i; /* Swaparoo! */ + } + truebyteswide = ci->w + 7 >> 3; /* >> divides by 8 */ + bytestooutput = (ci->w + 15 >> 4) * 2; /* >> divides by 16 */ +#ifdef ASCIILOAD + for (row = 0; row < ci->h; row++) { +#else + for (row = 0; row < ci->h; row++) +#endif + for (bytes = 0; bytes < bytestooutput; bytes++) { + if (bytes == truebyteswide - 1) + *(ci->bitmap + row * truebyteswide + bytes) &= + 0xFF<<7-(ci->w+7)%8; + if (bytes < truebyteswide) { + i = *(ci->bitmap + row * truebyteswide + bytes) & + 0xFF; +#ifdef ASCIILOAD + printf("%c%c", "0123456789ABCDEF"[i >> 4], + "0123456789ABCDEF"[i & 0xF]); +#else + if (i == '^') + printf("^^"); + else + (void)putchar(i); +#endif + } else +#ifdef ASCIILOAD + printf("00"); +#else + (void)putchar(0); +#endif + } +#ifdef ASCIILOAD + putchar('\n'); + } +#endif + break; + } /* End switch */ +#ifdef ASCIILOAD + printf("%s%s", ENDCMD, FREEOFF); +#else + printf("%s%s", ENDCMD, EIGHTBITOFF); +#endif + putchar('\r'); /* Ends the pass */ + (void)sigblock(SIGINT); + printf("%s00000%s", TAB, ENDCMD); + printf("%s00000%s", JUSTIFYMARGIN, ENDCMD); + SigStruct.sv_handler = callcleanup; + (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL); + seteoffunction(troffeofsocleanup); + CurRamBlocks += fn->blocksize; + fn->flags |= LOADED; + (void)sigsetmask(sigblock(0) & ~SIGINT); + return TRUE; +} + +/* The following routines are called when a SIGINT is received or EOF is + * unexpectedly encountered when reading a file. + */ +simplyexit() +{ + exit(SUCCEED); +} + +callcleanup() +{ + void cleanup(); + + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, SUCCEED); /* Interrupting a program is not an error */ +} + +void troffeofsocleanup() +{ + fprintf(stderr, "%s: unexpected EOF when reading otroff file\n", + Whoami); + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, 2); +} + +void pkeofsocleanup() +{ + fprintf(stderr, "%s: unexpected EOF when reading PK file %s\n", Whoami, + EOFName); + fputs(FORMFEED, stdout), NumPages++; + cleanup(FontList, 2); +} + +downloadinterrupt() +{ + fputs(ENDCMD, stdout); +#ifdef ASCIILOAD + fputs(FREEOFF, stdout); +#else + fputs(EIGHTBITOFF, stdout); +#endif + printf("%s%05d%c%s", DOWNLOAD, DownLoadFNum, Orientation, ENDCMD); + callcleanup(); +} + +void downloadpkeofsocleanup() +{ + fputs(ENDCMD, stdout); +#ifdef ASCIILOAD + fputs(FREEOFF, stdout); +#else + fputs(EIGHTBITOFF, stdout); +#endif + printf("%s%05d%c%s", DOWNLOAD, DownLoadFNum, Orientation, ENDCMD); + pkeofsocleanup(); +} diff --git a/dviware/quicspool/src/tfm2difont.c b/dviware/quicspool/src/tfm2difont.c new file mode 100644 index 0000000000..4fa2c12560 --- /dev/null +++ b/dviware/quicspool/src/tfm2difont.c @@ -0,0 +1,489 @@ +#ifndef lint +static char *rcs = "$Header: tfm2difont.c,v 1.1 88/01/15 13:05:47 simpson Rel $"; +#endif +/* +$Log: tfm2difont.c,v $ + * Revision 1.1 88/01/15 13:05:47 simpson + * initial release + * + * Revision 0.2 88/01/06 08:57:45 simpson + * added l. and L. for pic dots + * + * Revision 0.1 87/12/11 18:31:24 simpson + * beta test + * +*/ +#include <stdio.h> +#include <local/standard.h> +#include "constants.h" +#include "dev.h" + +/* An octal number designates that the character isn't normally in troff */ +char *NormalSequences[][5] = { /* Troff representations */ + /* Put the 1/6 em \| in the 000 position */ + /* 000 */ "\\|", NULL, NULL, NULL, NULL, + /* 001 */ "fi", NULL, NULL, NULL, NULL, + /* 002 */ "fl", NULL, NULL, NULL, NULL, + /* 003 */ "ff", NULL, NULL, NULL, NULL, + /* 004 */ "\\-", "en", NULL, NULL, NULL, + /* 005 */ "ru", NULL, NULL, NULL, NULL, + /* 006 */ "em", NULL, NULL, NULL, NULL, + /* 007 */ "bu", NULL, NULL, NULL, NULL, + /* 010 */ "sq", NULL, NULL, NULL, NULL, + /* 011 */ "fI", "Fi", NULL, NULL, NULL, + /* 012 */ "fL", "Fl", NULL, NULL, NULL, + /* 013 */ "de", NULL, NULL, NULL, NULL, + /* 014 */ "dg", NULL, NULL, NULL, NULL, + /* 015 */ "fm", NULL, NULL, NULL, NULL, + /* 016 */ "co", NULL, NULL, NULL, NULL, + /* 017 */ "rg", NULL, NULL, NULL, NULL, + /* 020 */ "ct", NULL, NULL, NULL, NULL, + /* 021 */ "14", NULL, NULL, NULL, NULL, + /* 022 */ "12", NULL, NULL, NULL, NULL, + /* 023 */ "34", NULL, NULL, NULL, NULL, + /* The following four characters (box, open bullet, umlaut and cedilla) */ + /* are not in otroff but are in ditroff. */ + /* 024 */ "bx", NULL, NULL, NULL, NULL, + /* 025 */ "ob", NULL, NULL, NULL, NULL, + /* 026 */ "..", NULL, NULL, NULL, NULL, + /* 027 */ "cd", NULL, NULL, NULL, NULL, + /* 030 */ "L.", "l.", NULL, NULL, NULL, + /* 031 */ "\031", NULL, NULL, NULL, NULL, + /* 032 */ "\032", NULL, NULL, NULL, NULL, + /* 033 */ "\033", NULL, NULL, NULL, NULL, + /* 034 */ "\034", NULL, NULL, NULL, NULL, + /* 035 */ "\035", NULL, NULL, NULL, NULL, + /* 036 */ "\036", NULL, NULL, NULL, NULL, + /* 037 */ "\037", NULL, NULL, NULL, NULL, + /* 040 */ " ", NULL, NULL, NULL, NULL, + /* 041 */ "!", NULL, NULL, NULL, NULL, + /* 042 */ "\042", NULL, NULL, NULL, NULL, + /* 043 */ "\043", NULL, NULL, NULL, NULL, + /* 044 */ "$", NULL, NULL, NULL, NULL, + /* 045 */ "%", NULL, NULL, NULL, NULL, + /* 046 */ "&", NULL, NULL, NULL, NULL, + /* 047 */ "\047", NULL, NULL, NULL, NULL, + /* 050 */ "(", NULL, NULL, NULL, NULL, + /* 051 */ ")", NULL, NULL, NULL, NULL, + /* 052 */ "*", NULL, NULL, NULL, NULL, + /* 053 */ "+", NULL, NULL, NULL, NULL, + /* 054 */ ",", NULL, NULL, NULL, NULL, + /* 055 */ "-", "hy", NULL, NULL, NULL, + /* 056 */ ".", NULL, NULL, NULL, NULL, + /* 057 */ "/", NULL, NULL, NULL, NULL, + /* 060 */ "0", NULL, NULL, NULL, NULL, + /* 061 */ "1", NULL, NULL, NULL, NULL, + /* 062 */ "2", NULL, NULL, NULL, NULL, + /* 063 */ "3", NULL, NULL, NULL, NULL, + /* 064 */ "4", NULL, NULL, NULL, NULL, + /* 065 */ "5", NULL, NULL, NULL, NULL, + /* 066 */ "6", NULL, NULL, NULL, NULL, + /* 067 */ "7", NULL, NULL, NULL, NULL, + /* 070 */ "8", NULL, NULL, NULL, NULL, + /* 071 */ "9", NULL, NULL, NULL, NULL, + /* 072 */ ":", NULL, NULL, NULL, NULL, + /* 073 */ ";", NULL, NULL, NULL, NULL, + /* 074 */ "\074", NULL, NULL, NULL, NULL, + /* 075 */ "\075", NULL, NULL, NULL, NULL, + /* 076 */ "\076", NULL, NULL, NULL, NULL, + /* 077 */ "?", NULL, NULL, NULL, NULL, + /* 100 */ "\100", NULL, NULL, NULL, NULL, + /* 101 */ "A", NULL, NULL, NULL, NULL, + /* 102 */ "B", NULL, NULL, NULL, NULL, + /* 103 */ "C", NULL, NULL, NULL, NULL, + /* 104 */ "D", NULL, NULL, NULL, NULL, + /* 105 */ "E", NULL, NULL, NULL, NULL, + /* 106 */ "F", NULL, NULL, NULL, NULL, + /* 107 */ "G", NULL, NULL, NULL, NULL, + /* 110 */ "H", NULL, NULL, NULL, NULL, + /* 111 */ "I", NULL, NULL, NULL, NULL, + /* 112 */ "J", NULL, NULL, NULL, NULL, + /* 113 */ "K", NULL, NULL, NULL, NULL, + /* 114 */ "L", NULL, NULL, NULL, NULL, + /* 115 */ "M", NULL, NULL, NULL, NULL, + /* 116 */ "N", NULL, NULL, NULL, NULL, + /* 117 */ "O", NULL, NULL, NULL, NULL, + /* 120 */ "P", NULL, NULL, NULL, NULL, + /* 121 */ "Q", NULL, NULL, NULL, NULL, + /* 122 */ "R", NULL, NULL, NULL, NULL, + /* 123 */ "S", NULL, NULL, NULL, NULL, + /* 124 */ "T", NULL, NULL, NULL, NULL, + /* 125 */ "U", NULL, NULL, NULL, NULL, + /* 126 */ "V", NULL, NULL, NULL, NULL, + /* 127 */ "W", NULL, NULL, NULL, NULL, + /* 130 */ "X", NULL, NULL, NULL, NULL, + /* 131 */ "Y", NULL, NULL, NULL, NULL, + /* 132 */ "Z", NULL, NULL, NULL, NULL, + /* 133 */ "[", NULL, NULL, NULL, NULL, + /* 134 */ "\134", NULL, NULL, NULL, NULL, + /* 135 */ "]", NULL, NULL, NULL, NULL, + /* 136 */ "\136", NULL, NULL, NULL, NULL, + /* 137 */ "_", NULL, NULL, NULL, NULL, + /* 140 */ "\140", NULL, NULL, NULL, NULL, + /* 141 */ "a", NULL, NULL, NULL, NULL, + /* 142 */ "b", NULL, NULL, NULL, NULL, + /* 143 */ "c", NULL, NULL, NULL, NULL, + /* 144 */ "d", NULL, NULL, NULL, NULL, + /* 145 */ "e", NULL, NULL, NULL, NULL, + /* 146 */ "f", NULL, NULL, NULL, NULL, + /* 147 */ "g", NULL, NULL, NULL, NULL, + /* 150 */ "h", NULL, NULL, NULL, NULL, + /* 151 */ "i", NULL, NULL, NULL, NULL, + /* 152 */ "j", NULL, NULL, NULL, NULL, + /* 153 */ "k", NULL, NULL, NULL, NULL, + /* 154 */ "l", NULL, NULL, NULL, NULL, + /* 155 */ "m", NULL, NULL, NULL, NULL, + /* 156 */ "n", NULL, NULL, NULL, NULL, + /* 157 */ "o", NULL, NULL, NULL, NULL, + /* 160 */ "p", NULL, NULL, NULL, NULL, + /* 161 */ "q", NULL, NULL, NULL, NULL, + /* 162 */ "r", NULL, NULL, NULL, NULL, + /* 163 */ "s", NULL, NULL, NULL, NULL, + /* 164 */ "t", NULL, NULL, NULL, NULL, + /* 165 */ "u", NULL, NULL, NULL, NULL, + /* 166 */ "v", NULL, NULL, NULL, NULL, + /* 167 */ "w", NULL, NULL, NULL, NULL, + /* 170 */ "x", NULL, NULL, NULL, NULL, + /* 171 */ "y", NULL, NULL, NULL, NULL, + /* 172 */ "z", NULL, NULL, NULL, NULL, + /* 173 */ "\173", NULL, NULL, NULL, NULL, + /* 174 */ "|", NULL, NULL, NULL, NULL, + /* 175 */ "\175", NULL, NULL, NULL, NULL, + /* 176 */ "\176", NULL, NULL, NULL, NULL, + /* Put the 1/12 em \^ in this position */ + /* 177 */ "\\^", NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL +}; +char *SpecialSequences[][5] = { /* Troff representations */ + /* 000 */ "\000", NULL, NULL, NULL, NULL, + /* 001 */ "if", NULL, NULL, NULL, NULL, + /* 002 */ "ip", NULL, NULL, NULL, NULL, + /* 003 */ "pt", NULL, NULL, NULL, NULL, + /* 004 */ "rh", NULL, NULL, NULL, NULL, + /* 005 */ "cu", NULL, NULL, NULL, NULL, + /* 006 */ "rn", NULL, NULL, NULL, NULL, + /* 007 */ "bs", NULL, NULL, NULL, NULL, + /* 010 */ "+-", NULL, NULL, NULL, NULL, + /* 011 */ "<=", NULL, NULL, NULL, NULL, + /* 012 */ ">=", NULL, NULL, NULL, NULL, + /* 013 */ "sr", NULL, NULL, NULL, NULL, + /* 014 */ "ts", NULL, NULL, NULL, NULL, + /* 015 */ "is", NULL, NULL, NULL, NULL, + /* 016 */ "sl", NULL, NULL, NULL, NULL, + /* 017 */ "bv", NULL, NULL, NULL, NULL, + /* 020 */ "lf", NULL, NULL, NULL, NULL, + /* 021 */ "rf", NULL, NULL, NULL, NULL, + /* 022 */ "lc", NULL, NULL, NULL, NULL, + /* 023 */ "rc", NULL, NULL, NULL, NULL, + /* 024 */ "lt", NULL, NULL, NULL, NULL, + /* 025 */ "lb", NULL, NULL, NULL, NULL, + /* 026 */ "rt", NULL, NULL, NULL, NULL, + /* 027 */ "rb", NULL, NULL, NULL, NULL, + /* 030 */ "lk", NULL, NULL, NULL, NULL, + /* 031 */ "rk", NULL, NULL, NULL, NULL, + /* 032 */ "sb", NULL, NULL, NULL, NULL, + /* 033 */ "sp", NULL, NULL, NULL, NULL, + /* 034 */ "ca", NULL, NULL, NULL, NULL, + /* 035 */ "no", NULL, NULL, NULL, NULL, + /* 036 */ "lh", NULL, NULL, NULL, NULL, + /* 037 */ "mo", NULL, NULL, NULL, NULL, + /* 040 */ "\040", NULL, NULL, NULL, NULL, + /* 041 */ "ul", "\\_", NULL, NULL, NULL, + /* 042 */ "\"", NULL, NULL, NULL, NULL, + /* 043 */ "#", NULL, NULL, NULL, NULL, + /* 044 */ "Sl", NULL, NULL, NULL, NULL, + /* 045 */ "\045", NULL, NULL, NULL, NULL, + /* 046 */ "\046", NULL, NULL, NULL, NULL, + /* 047 */ "'", "aa", NULL, NULL, NULL, + /* 050 */ "gr", NULL, NULL, NULL, NULL, + /* 051 */ "\051", NULL, NULL, NULL, NULL, + /* 052 */ "mu", NULL, NULL, NULL, NULL, + /* 053 */ "pl", NULL, NULL, NULL, NULL, + /* 054 */ "\054", NULL, NULL, NULL, NULL, + /* 055 */ "mi", NULL, NULL, NULL, NULL, + /* 056 */ "\056", NULL, NULL, NULL, NULL, + /* 057 */ "di", NULL, NULL, NULL, NULL, + /* 060 */ "==", NULL, NULL, NULL, NULL, + /* 061 */ "~=", "~~", NULL, NULL, NULL, + /* 062 */ "ap", NULL, NULL, NULL, NULL, + /* 063 */ "!=", NULL, NULL, NULL, NULL, + /* 064 */ "<-", NULL, NULL, NULL, NULL, + /* 065 */ "->", NULL, NULL, NULL, NULL, + /* 066 */ "ua", NULL, NULL, NULL, NULL, + /* 067 */ "da", NULL, NULL, NULL, NULL, + /* 070 */ "sc", NULL, NULL, NULL, NULL, + /* 071 */ "**", NULL, NULL, NULL, NULL, + /* 072 */ "\072", NULL, NULL, NULL, NULL, + /* 073 */ "\073", NULL, NULL, NULL, NULL, + /* 074 */ "<", NULL, NULL, NULL, NULL, + /* 075 */ "=", "eq", NULL, NULL, NULL, + /* 076 */ ">", NULL, NULL, NULL, NULL, + /* 077 */ "\077", NULL, NULL, NULL, NULL, + /* 100 */ "@", NULL, NULL, NULL, NULL, + /* 101 */ "*A", NULL, NULL, NULL, NULL, + /* 102 */ "*B", NULL, NULL, NULL, NULL, + /* 103 */ "*G", NULL, NULL, NULL, NULL, + /* 104 */ "*D", NULL, NULL, NULL, NULL, + /* 105 */ "*E", NULL, NULL, NULL, NULL, + /* 106 */ "*Z", NULL, NULL, NULL, NULL, + /* 107 */ "*Y", NULL, NULL, NULL, NULL, + /* 110 */ "*H", NULL, NULL, NULL, NULL, + /* 111 */ "*I", NULL, NULL, NULL, NULL, + /* 112 */ "*K", NULL, NULL, NULL, NULL, + /* 113 */ "*L", NULL, NULL, NULL, NULL, + /* 114 */ "*M", NULL, NULL, NULL, NULL, + /* 115 */ "*N", NULL, NULL, NULL, NULL, + /* 116 */ "*C", NULL, NULL, NULL, NULL, + /* 117 */ "*O", NULL, NULL, NULL, NULL, + /* 120 */ "*P", NULL, NULL, NULL, NULL, + /* 121 */ "*R", NULL, NULL, NULL, NULL, + /* 122 */ "*S", NULL, NULL, NULL, NULL, + /* 123 */ "*T", NULL, NULL, NULL, NULL, + /* 124 */ "*U", "U", NULL, NULL, NULL, + /* 125 */ "*F", NULL, NULL, NULL, NULL, + /* 126 */ "*X", NULL, NULL, NULL, NULL, + /* 127 */ "*Q", NULL, NULL, NULL, NULL, + /* 130 */ "*W", NULL, NULL, NULL, NULL, + /* 131 */ "dd", NULL, NULL, NULL, NULL, + /* 132 */ "br", NULL, NULL, NULL, NULL, + /* 133 */ "ib", NULL, NULL, NULL, NULL, + /* 134 */ "\\", NULL, NULL, NULL, NULL, + /* 135 */ "ci", NULL, NULL, NULL, NULL, + /* 136 */ "^", NULL, NULL, NULL, NULL, + /* 137 */ "_", NULL, NULL, NULL, NULL, + /* 140 */ "`", "ga", NULL, NULL, NULL, + /* 141 */ "*a", NULL, NULL, NULL, NULL, + /* 142 */ "*b", NULL, NULL, NULL, NULL, + /* 143 */ "*g", NULL, NULL, NULL, NULL, + /* 144 */ "*d", NULL, NULL, NULL, NULL, + /* 145 */ "*e", NULL, NULL, NULL, NULL, + /* 146 */ "*z", NULL, NULL, NULL, NULL, + /* 147 */ "*y", NULL, NULL, NULL, NULL, + /* 150 */ "*h", NULL, NULL, NULL, NULL, + /* 151 */ "*i", NULL, NULL, NULL, NULL, + /* 152 */ "*k", NULL, NULL, NULL, NULL, + /* 153 */ "*l", NULL, NULL, NULL, NULL, + /* 154 */ "*m", NULL, NULL, NULL, NULL, + /* 155 */ "*n", NULL, NULL, NULL, NULL, + /* 156 */ "*c", NULL, NULL, NULL, NULL, + /* 157 */ "*o", NULL, NULL, NULL, NULL, + /* 160 */ "*p", NULL, NULL, NULL, NULL, + /* 161 */ "*r", NULL, NULL, NULL, NULL, + /* 162 */ "*s", NULL, NULL, NULL, NULL, + /* 163 */ "*t", NULL, NULL, NULL, NULL, + /* 164 */ "*u", NULL, NULL, NULL, NULL, + /* 165 */ "*f", NULL, NULL, NULL, NULL, + /* 166 */ "*x", NULL, NULL, NULL, NULL, + /* 167 */ "*q", NULL, NULL, NULL, NULL, + /* 170 */ "*w", NULL, NULL, NULL, NULL, + /* 171 */ "pd", NULL, NULL, NULL, NULL, + /* 172 */ "es", NULL, NULL, NULL, NULL, + /* 173 */ "{", NULL, NULL, NULL, NULL, + /* 174 */ "or", "vr", NULL, NULL, NULL, + /* 175 */ "}", NULL, NULL, NULL, NULL, + /* 176 */ "~", NULL, NULL, NULL, NULL, + /* 177 */ "\177", NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL +}; + +char TfmName[81]; /* Only used in error routine */ +char *WhoAmI; /* Argv[0] */ +char *Usage = "Usage: %s [-s] [-w width] [-l ligature]... file...\n"; +Boolean Special = FALSE; /* Designates whether font is special. */ +Bits Ligatures; /* Ligatures the font does not contain. */ +int ExitStatus = SUCCEED; +int Width = -1; /* "spacewidth" in font desc. file. -1==omit */ + +main(argc,argv) +int argc; +char *argv[]; +{ + extern int optind; + extern char *optarg; + int c; + FILE *infile, *outfile; + void seteoffunction(), tfmeofsoexit(), convert(); + char *strcpy(); + + WhoAmI = argv[0]; + while ((c = getopt(argc, argv, "sl:w:")) != EOF) + switch (c) { + case 's': + Special = TRUE; + break; + case 'w': + Width = atoi(optarg); + break; + case 'l': + if (EQ(optarg, "ff")) + Ligatures |= LFF; + else if (EQ(optarg, "fi")) + Ligatures |= LFI; + else if (EQ(optarg, "fl")) + Ligatures |= LFL; + else if (EQ(optarg, "ffi")) + Ligatures |= LFFI; + else if (EQ(optarg, "ffl")) + Ligatures |= LFFL; + break; + case '?': + fprintf(stderr, Usage, WhoAmI); + exit(FAIL); + } + seteoffunction(tfmeofsoexit); + for (; optind < argc; optind++) { + if (strlen(argv[optind]) < 5 || !EQ(".tfm", + &argv[optind][strlen(argv[optind])-4])) { + fprintf(stderr, "%s: invalid input file name %s\n", WhoAmI, + argv[optind]); + ExitStatus = FAIL; + continue; + } + if (!(infile = fopen(argv[optind], "r"))) { + fprintf(stderr, "%s: cannot open input file %s\n", WhoAmI, + argv[optind]); + ExitStatus = FAIL; + continue; + } + (void)strcpy(TfmName, argv[optind]); + argv[optind][strlen(argv[optind])-4] = '\0'; + if (!(outfile = fopen(argv[optind], "w"))) { + fprintf(stderr, "%s: cannot open output file %s\n", WhoAmI, + argv[optind]); + ExitStatus = FAIL; + continue; + } + convert(infile, outfile, argv[optind]); + (void)fclose(infile), (void)fclose(outfile); + } + exit(ExitStatus); +} + +/* The main routine which converts a tfm file to a troff width table file. + */ +void convert(infile, outfile, outname) +FILE *infile, *outfile; +char *outname; /* Output file name */ +{ + int aheight, i, j, widthindex, heightanddepth, width, + height, depth, kerning; + unsigned long uinteger(), lh, bc, ec, nw, nh, designsize, utemp; + long integer(), temp; + + fprintf(outfile, "name %s\ninternalname %s\n", outname, outname); + if (Special) + fputs("special\n", outfile); + if (!Special && Ligatures != 0x1F) { + fputs("ligatures ", outfile); + if (!(Ligatures & LFF)) + fputs("ff ", outfile); + if (!(Ligatures & LFI)) + fputs("fi ", outfile); + if (!(Ligatures & LFL)) + fputs("fl ", outfile); + if (!(Ligatures & LFFI)) + fputs("ffi ", outfile); + if (!(Ligatures & LFFL)) + fputs("ffl ", outfile); + fputs("0\n", outfile); + } + if (Width != -1) + fprintf(outfile, "spacewidth %d\n", Width); + if (!Special) { + if ((aheight = getaheight(infile)) == MAX_INTEGER) { + fprintf(stderr, "%s: no letter 'a' in file %s.tfm\n", WhoAmI, + outname); + fprintf(stderr, "\tsetting height to zero\n"); + aheight = 0; + } + (void)fseek(infile, 0L, 0); + } + fputs("charset\n", outfile); + (void)uinteger(infile, 2); /* lf */ + lh = uinteger(infile, 2); + bc = uinteger(infile, 2); + ec = uinteger(infile, 2); + nw = uinteger(infile, 2); + nh = uinteger(infile, 2); + (void)uinteger(infile, 2); /* nd */ + (void)uinteger(infile, 2); /* ni */ + (void)uinteger(infile, 2); /* nl */ + (void)uinteger(infile, 2); /* nk */ + (void)uinteger(infile, 2); /* ne */ + (void)uinteger(infile, 2); /* np */ + (void)uinteger(infile, 4); /* Skip checksum */ + designsize = uinteger(infile, 4) / FIX; + for (i = bc; i <= ec; i++) { + (void)fseek(infile, 24L + 4*lh + (i-bc)*4, 0); + widthindex = uinteger(infile, 1); + heightanddepth = uinteger(infile, 1); + if (widthindex == 0) + continue; + (void)fseek(infile, 24L + 4*lh + (ec-bc+1)*4 + widthindex*4, 0); + temp = integer(infile, 4); + width = ROUND((temp / (double)FIX * designsize) / PPI * RESOLUTION); + (void)fseek(infile, 24L + 4*lh + (ec-bc+1)*4 + nw*4 + + (heightanddepth>>4)*4, 0); + utemp = uinteger(infile, 4); + height = ROUND((utemp / (double)FIX * designsize) / PPI * RESOLUTION); + (void)fseek(infile, 24L + 4*lh + (ec-bc+1)*4 + nw*4 + nh*4 + + (heightanddepth&0xF)*4, 0); + utemp = uinteger(infile, 4); + depth = ROUND((utemp / (double)FIX * designsize) / PPI * RESOLUTION); + kerning = 0; + if (height > aheight) + kerning |= 2; + if (depth > 0) + kerning |= 1; + for (j = 0; Special ? SpecialSequences[i][j] : NormalSequences[i][j]; + j++) + if (j == 0) + fprintf(outfile, "%s\t%d\t%d\t%d\n", Special ? + SpecialSequences[i][j] : NormalSequences[i][j], width, + Special ? 0 : kerning, i); + else + fprintf(outfile, "%s\t\"\n", Special ? SpecialSequences[i][j] : + NormalSequences[i][j]); + } +} + +/* Returns the height of the letter 'a' in the font passed as a parameter. + * The height is returned in pixels since troff likes to use pixels as its + * unit. If the letter 'a' is not found, MAX_INTEGER is returned. + */ +int getaheight(in) +FILE *in; +{ + unsigned long lh, bc, ec, nw, uinteger(), designsize; + + (void)fseek(in, 0L, 0); + (void)uinteger(in, 2); /* lf */ + lh = uinteger(in, 2); + bc = uinteger(in, 2); + ec = uinteger(in, 2); + nw = uinteger(in, 2); + (void)uinteger(in, 2); /* nh */ + (void)uinteger(in, 2); /* nd */ + (void)uinteger(in, 2); /* ni */ + (void)uinteger(in, 2); /* nl */ + (void)uinteger(in, 2); /* nk */ + (void)uinteger(in, 2); /* ne */ + (void)uinteger(in, 2); /* np */ + if (bc > 'a' || ec < 'a') + return MAX_INTEGER; + (void)uinteger(in, 4); /* Skip checksum */ + designsize = uinteger(in, 4) / FIX; /* Convert from FIXes */ + (void)fseek(in, 24L + lh*4 + ('a'-bc)*4, 0); + if (uinteger(in, 1) == 0) + return MAX_INTEGER; + (void)fseek(in, 24L + lh*4 + (ec-bc+1)*4 + nw*4 + (uinteger(in,1) >> 4)*4, + 0); + return ROUND((uinteger(in, 4) / (double)FIX * designsize) / PPI * + RESOLUTION); +} + +void tfmeofsoexit() +{ + fprintf(stderr, "%s: unexpected end of tfm file %s\n", WhoAmI, TfmName); + exit(FAIL); +} diff --git a/dviware/quicspool/src/tfm2ofont.c b/dviware/quicspool/src/tfm2ofont.c new file mode 100644 index 0000000000..d40d38098e --- /dev/null +++ b/dviware/quicspool/src/tfm2ofont.c @@ -0,0 +1,231 @@ +#ifndef lint +static char *rcs = "$Header: tfm2ofont.c,v 1.1 88/01/15 13:05:54 simpson Rel $"; +#endif +/* +$Log: tfm2ofont.c,v $ + * Revision 1.1 88/01/15 13:05:54 simpson + * initial release + * + * Revision 0.1 87/12/11 18:31:26 simpson + * beta test + * +*/ +#include <stdio.h> +#include <ctype.h> +#include <local/standard.h> +#include "constants.h" + +extern char RegularOrder[], SpecialOrder[]; /* Order we want to output */ + +char OutputFile[81]; +char TfmName[81]; /* Only used in error routine */ +char *WhoAmI; /* Argv[0] */ +char *Usage = "Usage: %s [-s] file...\n"; +Boolean Special = FALSE; /* Designates whether font is special */ +int ExitStatus = SUCCEED; + +main(argc, argv) +int argc; +char *argv[]; +{ + extern int optind; + extern char *optarg; + int c; + FILE *infile, *outfile; + void seteoffunction(), tfmeofsoexit(), convert(); + char *strcpy(), *strcat(), *strncat(); + + WhoAmI = argv[0]; + while ((c = getopt(argc, argv, "s")) != EOF) + switch (c) { + case 's': + Special = TRUE; + break; + case '?': + fprintf(stderr, Usage, WhoAmI); + exit(FAIL); + } + seteoffunction(tfmeofsoexit); + for (; optind < argc; optind++) { + if (strlen(argv[optind]) < 5 || !EQ(".tfm", &argv[optind][strlen( + argv[optind])-4])) { + fprintf(stderr, "%s: invalid input file name %s\n", WhoAmI, + argv[optind]); + ExitStatus = FAIL; + continue; + } + if (!(infile = fopen(argv[optind], "r"))) { + fprintf(stderr, "%s: cannot open input file %s\n", WhoAmI, + argv[optind]); + ExitStatus = FAIL; + continue; + } + (void)strcpy(TfmName, argv[optind]); + (void)strcpy(OutputFile, "ft"); + (void)strncat(OutputFile, argv[optind], strlen(argv[optind])-4); + (void)strcat(OutputFile, ".c"); + if (!(outfile = fopen(OutputFile, "w"))) { + fprintf(stderr, "%s: cannot open output file %s\n", WhoAmI, + OutputFile); + ExitStatus = FAIL; + continue; + } + convert(infile, outfile, argv[optind]); + (void)fclose(infile), (void)fclose(outfile); + } + exit(ExitStatus); +} + +/* The main routine which converts a tfm file to an otroff width table file. + */ +void convert(infile, outfile, inname) +FILE *infile, *outfile; +char *inname; +{ + long aheight, i, j, widthindex, heightanddepth, zero, height, + depth, charpos; + long widths[256][2]; /* Width of char in FIX/designsize & kern */ + unsigned long uinteger(), lh, bc, ec, nw, nh, designsize; + long integer(), getaheight(); + + fprintf(outfile, "char font[256-32] = {\n"); + if ((aheight = getaheight(infile)) == MAX_INTEGER) { + fprintf(stderr, "%s: no letter 'a' in file %s\n", WhoAmI, inname); + fprintf(stderr, "\tsetting height to zero\n"); + aheight = 0; + } + rewind(infile); + bzero((char *)widths, sizeof(widths)); + (void)uinteger(infile, 2); /* lf */ + lh = uinteger(infile, 2); + bc = uinteger(infile, 2); + ec = uinteger(infile, 2); + nw = uinteger(infile, 2); + nh = uinteger(infile, 2); + (void)uinteger(infile, 2); /* nd */ + (void)uinteger(infile, 2); /* ni */ + (void)uinteger(infile, 2); /* nl */ + (void)uinteger(infile, 2); /* nk */ + (void)uinteger(infile, 2); /* ne */ + (void)uinteger(infile, 2); /* np */ + (void)uinteger(infile, 4); /* Skip checksum */ + designsize = uinteger(infile, 4) / FIX; + for (i = bc; i <= ec; i++) { + (void)fseek(infile, 24L + 4 * lh + (i - bc) * 4, 0); + widthindex = uinteger(infile, 1); + heightanddepth = uinteger(infile, 1); + if (widthindex == 0) + continue; + (void)fseek(infile, 24L + 4 * lh + (ec - bc + 1) * 4 + widthindex + * 4, 0); + widths[i][0] = integer(infile, 4); + (void)fseek(infile, 24L + 4 * lh + (ec - bc + 1) * 4 + nw * 4 + + (heightanddepth >> 4) * 4, 0); + height = uinteger(infile, 4); + (void)fseek(infile, 24L + 4 * lh + (ec - bc + 1) * 4 + nw * 4 + + nh * 4 + (heightanddepth & 0xF) * 4, 0); + depth = uinteger(infile, 4); + if (!Special && isalnum(i) || Special && (0101 <= i && i <= 0130 + || 0141 <= i && i <= 0170 || i == 014 || i == 050)) { + if (height > aheight) /* Letters taller than 'a' get 0200 */ + widths[i][1] |= 0200; /* turned on. */ + if (depth > 0) /* Letters below baseline get 0100 */ + widths[i][1] |= 0100; /* turned on. */ + } + } + for (i = 040, zero = 0; i < 256; i++) { + if (i == 0177 && !Special) { /* 1/16em is always 6 units */ + if (zero) { + zero = 0; + putc('\n', outfile); + } + fprintf(outfile, "6,\n"); + continue; + } + if (i == 0226 && !Special) { /* 1/12em is always 3 units */ + if (zero) { + zero = 0; + putc('\n', outfile); + } + fprintf(outfile, "3,\n"); + continue; + } + if (i == ' ' && !Special) { /* Space is always 12 units */ + if (zero) { + zero = 0; + putc('\n', outfile); + } + fprintf(outfile, "12,\n"); + continue; + } + charpos = (Special ? SpecialOrder[i - 32] : RegularOrder[i - 32]); + if (charpos == 0 || widths[charpos][0] == 0) { + fprintf(outfile, "0,"); + zero++; + if (!((i+1)%8)) { + putc('\n', outfile); + zero = 0; + } + } else { + if (zero) { + zero = 0; + putc('\n', outfile); + } + j = ROUND((widths[charpos][0] / (double)FIX * designsize) / PPI + * 254.6457); + /* Don't ask where the 254.6457 came from. I haven't the faintest + * notion why troff uses this constant, but it works, and that + * is fine enough with me. Otroff can't handle widths over + * 63 (2^6). If you give it something greater, it take the + * lower six bits. This screws up the TRW logo which is 79 but + * there is nothing we can do. + */ + fprintf(outfile, "%d", j > 63 ? 63 : j); + if (widths[charpos][1]) + fprintf(outfile, "+0%o,\n", widths[charpos][1]); + else + fprintf(outfile, ",\n"); + } + } + fprintf(outfile, "};\n"); +} + +/* Returns the height of the letter 'a' in the font passed as a parameter. + * The height is returned in FIXes/designsize. If the letter 'a' is not + * found, MAX_INTEGER is returned. + */ +long getaheight(in) +FILE *in; +{ + unsigned long lh, bc, ec, nw, uinteger(); + + (void)fseek(in, 0L, 0); + (void)uinteger(in, 2); /* lf */ + lh = uinteger(in, 2); + bc = uinteger(in, 2); + ec = uinteger(in, 2); + nw = uinteger(in, 2); + (void)uinteger(in, 2); /* nh */ + (void)uinteger(in, 2); /* nd */ + (void)uinteger(in, 2); /* ni */ + (void)uinteger(in, 2); /* nl */ + (void)uinteger(in, 2); /* nk */ + (void)uinteger(in, 2); /* ne */ + (void)uinteger(in, 2); /* np */ + if (bc > 'a' || ec < 'a') + return MAX_INTEGER; + (void)uinteger(in, 4); /* Skip checksum */ + (void)uinteger(in, 4); /* Width */ + (void)fseek(in, 24L + lh*4 + ('a'-bc)*4, 0); + if (uinteger(in, 1) == 0) + return MAX_INTEGER; + (void)fseek(in, 24L + lh*4 + (ec-bc+1)*4 + nw*4 + (uinteger(in,1) >> 4)*4, + 0); + return uinteger(in, 4); +} + +void tfmeofsoexit() +{ + fprintf(stderr, "%s: unexpected end of tfm file %s\n", WhoAmI, TfmName); + exit(FAIL); +} diff --git a/dviware/quicspool/src/xxx.y b/dviware/quicspool/src/xxx.y new file mode 100644 index 0000000000..304851484e --- /dev/null +++ b/dviware/quicspool/src/xxx.y @@ -0,0 +1,411 @@ +%{ +#ifndef lint +static char *yrcs = "$Header: xxx.y,v 1.2 88/02/03 08:52:12 simpson Exp $"; +#endif +/* +$Log: xxx.y,v $ + * Revision 1.2 88/02/03 08:52:12 simpson + * added tpic support + * + * Revision 1.1 88/01/15 13:05:57 simpson + * initial release + * + * Revision 0.1 87/12/11 18:31:27 simpson + * beta test + * +*/ +#define TPICRES 1000 /* Tpic uses 1000 dots/inch */ +static int Coordinates[300][2]; /* Coordinates used by tpic */ +static int CoorCount; /* Count of # of coor in above array */ +static int PenWidth; +static int GraphOrigin[2]; +static double Center[2], Cur[2], New[2]; +static double CurvePts[300][3], SplinePts[500][3]; +static enum {none, white, shade, black} Color; +%} +%union { + int i; + double f; + char s[81]; +} +%token OVERLAY PENSIZE FLUSHPATH FLUSHDASHED FLUSHDOTTED ADDPATH DRAWARC +%token FLUSHSPLINE SHADELAST WHITENLAST BLACKENLAST TEXTURE +%token <s> STRING +%token <i> INTEGER +%token <f> FLOAT +%type <s> validfile +%% +keywords : + keyword ',' keywords + | + keyword + | + error ',' + { + yyerrok; + } + keywords + ; + +keyword : + OVERLAY + '(' + validfile + { + FILE *f; + char filename[81], *expandtilde(), *strcpy(); + int c; + + (void)strcpy(filename, $3); + (void)expandtilde(filename); + if (f = fopen(filename, "r")) { + while ((c = getc(f)) != EOF) + (void)putchar(c); + (void)fclose(f); + } + } + ')' + | + PENSIZE + INTEGER + { + /* A pen command designates the start of a new graph */ + PenWidth = ROUND($2 / 1000.0 * RESOLUTION); + GraphOrigin[0] = Origin[0], GraphOrigin[1] = Origin[1]; + CoorCount = 0; + Color = none; + } + | + FLUSHPATH + { + if (CoorCount > 1) { + int i; + + fputs(VECTORON, stdout); + printf("%s%05d:%05d", PENUP, + ROUND((GraphOrigin[0]/(double)RESOLUTION+Coordinates[0][0]/(double)TPICRES)*1000), + ROUND((GraphOrigin[1]/(double)RESOLUTION+Coordinates[0][1]/(double)TPICRES)*1000)); + printf("%s%02d", PENWIDTH, PenWidth); + for (i = 1; i < CoorCount; i++) + printf("%s%05d:%05d", PENDOWN, + ROUND((GraphOrigin[0]/(double)RESOLUTION+Coordinates[i][0]/(double)TPICRES)*1000), + ROUND((GraphOrigin[1]/(double)RESOLUTION+Coordinates[i][1]/(double)TPICRES)*1000)); + fputs(VECTOROFF, stdout); + } + if (CoorCount >=4 && Color != none) { + /* Find midpoint of diagonal */ + Center[0] = ((GraphOrigin[0]/(double)RESOLUTION+ + Coordinates[0][0]/(double)TPICRES)+(GraphOrigin[0]/ + (double)RESOLUTION+Coordinates[2][0]/(double)TPICRES))/2.0; + Center[1] = ((GraphOrigin[1]/(double)RESOLUTION+ + Coordinates[0][1]/(double)TPICRES)+(GraphOrigin[1]/ + (double)RESOLUTION+Coordinates[2][1]/(double)TPICRES))/2.0; + printf("%s%05d%05d", AREAFILL, + ROUND(Center[0]*1000),ROUND(Center[1]*1000)); + switch (Color) { + case white: + printf("%02d", 0); + break; + case shade: + printf("%02d", 19); + break; + case black: + printf("%02d", 20); + break; + } + printf("%s", ENDCMD); + } + CoorCount = 0; + Color = none; + } + | + FLUSHDASHED + FLOAT + { + if (CoorCount > 1) { + int i; + + fputs(VECTORON, stdout); + printf("%s%05d:%05d", PENUP, + ROUND((GraphOrigin[0]/(double)RESOLUTION+Coordinates[0][0]/(double)TPICRES)*1000), + ROUND((GraphOrigin[1]/(double)RESOLUTION+Coordinates[0][1]/(double)TPICRES)*1000)); + printf("%s%02d", PENWIDTH, PenWidth); + printf("%s%d", "^V", 4); + for (i = 1; i < CoorCount; i++) + printf("%s%05d:%05d", PENDOWN, + ROUND((GraphOrigin[0]/(double)RESOLUTION+Coordinates[i][0]/(double)TPICRES)*1000), + ROUND((GraphOrigin[1]/(double)RESOLUTION+Coordinates[i][1]/(double)TPICRES)*1000)); + fputs(VECTOROFF, stdout); + } + CoorCount = 0; + Color = none; + } + | + FLUSHDOTTED + FLOAT + { + if (CoorCount > 1) { + int i; + + fputs(VECTORON, stdout); + printf("%s%05d:%05d", PENUP, + ROUND((GraphOrigin[0]/(double)RESOLUTION+Coordinates[0][0]/(double)TPICRES)*1000), + ROUND((GraphOrigin[1]/(double)RESOLUTION+Coordinates[0][1]/(double)TPICRES)*1000)); + printf("%s%02d", PENWIDTH, PenWidth); + printf("%s%d", "^V", 2); + for (i = 1; i < CoorCount; i++) + printf("%s%05d:%05d", PENDOWN, + ROUND((GraphOrigin[0]/(double)RESOLUTION+Coordinates[i][0]/(double)TPICRES)*1000), + ROUND((GraphOrigin[1]/(double)RESOLUTION+Coordinates[i][1]/(double)TPICRES)*1000)); + fputs(VECTOROFF, stdout); + } + CoorCount = 0; + Color = none; + } + | + ADDPATH + INTEGER + INTEGER + { + Coordinates[CoorCount][0] = $2, Coordinates[CoorCount++][1] = $3; + } + | + DRAWARC + INTEGER + INTEGER + INTEGER + INTEGER + FLOAT + FLOAT + { + Center[0] = GraphOrigin[0] / (double)RESOLUTION + $2 / + (double)TPICRES, + Center[1] = GraphOrigin[1] / (double)RESOLUTION + $3 / + (double)TPICRES; + if ($4 != $5) { /* Ellipse */ + int i; + + /* Ellipses satisfy the equation (x^2)/(a^2)+(y^2)/(b^2)=1 + * where 'a' is the length of the semimajor axis and 'b' + * is the length of the semiminor axis. We divide each + * quadrant into 200 line segments and connect the line + * segments. + */ + /* Cur and New are relative to the origin */ + Cur[0] = $4 / (double)TPICRES, Cur[1] = 0.0; + fputs(VECTORON, stdout); + printf("%s%02d", PENWIDTH, PenWidth); + for (i = 1; i <= 200; i++, Cur[0] = New[0], Cur[1] = New[1]) { + New[0] = ($4/(double)TPICRES)*cos((i/200.0)*(PI/2.0)), + New[1] = ($5/(double)TPICRES)*sin((i/200.0)*(PI/2.0)); + /* First quadrant */ + printf("%s%05d:%05d", PENUP, + ROUND((Center[0]+Cur[0])*1000.0), + ROUND((Center[1]+Cur[1])*1000.0)); + printf("%s%05d:%05d", PENDOWN, + ROUND((Center[0]+New[0])*1000.0), + ROUND((Center[1]+New[1])*1000.0)); + /* Second quadrant */ + printf("%s%05d:%05d", PENUP, + ROUND((Center[0]-Cur[0])*1000.0), + ROUND((Center[1]+Cur[1])*1000.0)); + printf("%s%05d:%05d", PENDOWN, + ROUND((Center[0]-New[0])*1000.0), + ROUND((Center[1]+New[1])*1000.0)); + /* Third quadrant */ + printf("%s%05d:%05d", PENUP, + ROUND((Center[0]-Cur[0])*1000.0), + ROUND((Center[1]-Cur[1])*1000.0)); + printf("%s%05d:%05d", PENDOWN, + ROUND((Center[0]-New[0])*1000.0), + ROUND((Center[1]-New[1])*1000.0)); + /* Fourth quadrant */ + printf("%s%05d:%05d", PENUP, + ROUND((Center[0]+Cur[0])*1000.0), + ROUND((Center[1]-Cur[1])*1000.0)); + printf("%s%05d:%05d", PENDOWN, + ROUND((Center[0]+New[0])*1000.0), + ROUND((Center[1]-New[1])*1000.0)); + if (Color != none) { + printf("%s%05d%05d", AREAFILL, + ROUND(Center[0]*1000),ROUND(Center[1]*1000)); + switch (Color) { + case white: + printf("%02d", 0); + break; + case shade: + printf("%02d", 19); + break; + case black: + printf("%02d", 20); + break; + } + printf("%s", ENDCMD); + Color = none; + } + } + fputs(VECTOROFF, stdout); + } else { /* Arc */ + printf("%s%c%05d%c%05d%05d%03d%03d%02d%s", DECIMALARC, + Center[0]>0?'+':'-', + Center[0]>0?ROUND(Center[0]*1000): + ROUND(-Center[0]*1000),Center[1]>0?'+':'-', + Center[1]>0?ROUND(Center[1]*1000): + ROUND(-Center[1]*1000),$4,ROUND($6/PI*500.0)>999?999: + ROUND($6/PI*500.0),ROUND($7/PI*500.0)>999?999: + ROUND($7/PI*500.0), PenWidth, ENDCMD); + if ($6 == 0 && ABS($7-2*PI) < 0.01) + if (Color != none) { + printf("%s%05d%05d", AREAFILL, + ROUND(Center[0]*1000),ROUND(Center[1]*1000)); + switch (Color) { + case white: + printf("%02d", 0); + break; + case shade: + printf("%02d", 19); + break; + case black: + printf("%02d", 20); + break; + } + printf("%s", ENDCMD); + Color = none; + } + } + } + + | + FLUSHSPLINE + { + if (CoorCount > 1) { + int i; + + for (i = 0; i < CoorCount; i++) { + CurvePts[i][0] = Coordinates[i][0] / (double)TPICRES; + CurvePts[i][1] = Coordinates[i][1] / (double)TPICRES; + CurvePts[i][2] = 0.0; /* z-axis not used */ + } + spline(CurvePts,CoorCount-1,SplinePts,499,3); /* 2nd degree */ + fputs(VECTORON, stdout); + printf("%s%05d:%05d", PENUP, + ROUND((GraphOrigin[0]/(double)RESOLUTION+SplinePts[0][0])*1000), + ROUND((GraphOrigin[1]/(double)RESOLUTION+SplinePts[0][1])*1000)); + printf("%s%02d", PENWIDTH, PenWidth); + for (i = 1; i < 500; i++) + printf("%s%05d:%05d", PENDOWN, + ROUND((GraphOrigin[0]/(double)RESOLUTION+SplinePts[i][0])*1000), + ROUND((GraphOrigin[1]/(double)RESOLUTION+SplinePts[i][1])*1000)); + fputs(VECTOROFF, stdout); + } + CoorCount = 0; + } + | + TEXTURE + textureargs /* Ignore - Imagen only */ + | + SHADELAST + { + Color = shade; + } + | + WHITENLAST + { + Color = white; + } + | + BLACKENLAST + { + Color = black; + } + ; + +validfile : + STRING + { + (void)strcpy($$, $1); + } + | + OVERLAY + { + (void)strcpy($$, "overlay"); + } + | + PENSIZE + { + (void)strcpy($$, "pn"); + } + | + FLUSHPATH + { + (void)strcpy($$, "fp"); + } + | + FLUSHDASHED + { + (void)strcpy($$, "da"); + } + | + FLUSHDOTTED + { + (void)strcpy($$, "dt"); + } + | + ADDPATH + { + (void)strcpy($$, "pa"); + } + | + DRAWARC + { + (void)strcpy($$, "ar"); + } + | + FLUSHSPLINE + { + (void)strcpy($$, "sp"); + } + | + SHADELAST + { + (void)strcpy($$, "sh"); + } + | + WHITENLAST + { + (void)strcpy($$, "wh"); + } + | + BLACKENLAST + { + (void)strcpy($$, "bk"); + } + | + TEXTURE + { + (void)strcpy($$, "tx"); + } + | + INTEGER + { + (void)sprintf($$, "%d", $1); + } +/* | Unfortunately this won't work since the lexeme + FLOAT of a float has been lost when we converted it to a + { real number. + (void)sprintf($$, "%f", $1); + } +*/ + ; + +textureargs : texturearg textureargs | /* epsilon */ ; + +texturearg : STRING | INTEGER ; +%% +#include "xxxlex.c" + +yyerror(s) +char *s; +{ + return; +} diff --git a/dviware/quicspool/src/xxxlex.l b/dviware/quicspool/src/xxxlex.l new file mode 100644 index 0000000000..5f48bebff1 --- /dev/null +++ b/dviware/quicspool/src/xxxlex.l @@ -0,0 +1,52 @@ +/* $Header: xxxlex.l,v 1.2 88/02/03 08:52:10 simpson Exp $ */ +%{ +/* +$Log: xxxlex.l,v $ + * Revision 1.2 88/02/03 08:52:10 simpson + * added tpic support + * + * Revision 1.1 88/01/15 13:06:01 simpson + * initial release + * + * Revision 0.1 87/12/11 18:31:28 simpson + * beta test + * +*/ +#undef input +#define input() (Pxxxstring && *Pxxxstring ? *Pxxxstring++ : 0) +#undef unput +#define unput(c) if (Pxxxstring > Xxxstring) *--Pxxxstring = c +%} +integer [0-9]+ +real [0-9]+\.[0-9]*|[0-9]*\.[0-9]+ +whitespace [ \t\n]+ +%% +{integer} { + yylval.i = atoi(yytext); + return INTEGER; + } +{real} { + yylval.f = atof(yytext); + return FLOAT; + } +pn return PENSIZE; +fp return FLUSHPATH; +da return FLUSHDASHED; +dt return FLUSHDOTTED; +pa return ADDPATH; +ar return DRAWARC; +sp return FLUSHSPLINE; +sh return SHADELAST; +wh return WHITENLAST; +bk return BLACKENLAST; +tx return TEXTURE; +[^\,\)\( \t\n]+ { + (void)strcpy(yylval.s, yytext); + if (EQ(yytext, "overlay")) + return OVERLAY; + return STRING; + } +\, | +\( | +\) return yytext[0]; +{whitespace} ; |