home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume20 / psroff / part04 / lj.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-17  |  8.9 KB  |  403 lines

  1. /*    Copyright 1985, 1986, 1987, 1988 Chris Lewis
  2.         All Rights Reserved
  3.  
  4.     Permission to copy and further distribute is freely given provided 
  5.     this copyright notice remains intact and that this software is not 
  6.     sold for profit.
  7.  
  8.     Project:    Generic Troff drivers
  9.     Module:        lj.c
  10.     Author:     Chris Lewis
  11.     Specs:        LaserJet driver, hacked from ps.c and lcat.c
  12.             (Gosh, this is a lot simpler than lcat's stuff.
  13.             Thank PostScript for getting my brain in order.)
  14.  
  15.             Font downloading is supported, but untested as
  16.             yet.
  17.             Font downloading is not supported yet, however
  18.             all of the font selection stuff is.  Therefore,
  19.             this stuff will actually work if all of the
  20.             fonts have been previously downloaded...
  21.             However, the LJ considers different point sizes
  22.             to be different fonts, so don't expect much....
  23.  
  24.             Macro "DOWNLOAD" is used to denote places and
  25.             some coding for font downloading.
  26.  
  27.             Without font downloading, this is LJ compatible.
  28.             Font downloading will require a LJ+, LJ500+ or
  29.             LJ II.
  30.  
  31.             This code has not been tested - however, it is
  32.             a derivitive of the original lcat software, so
  33.             it may actually do things right.  Chances are,
  34.             any errors are in some of the escape sequence
  35.             details.  Eg: the stroke-weight parameter may
  36.             need tweaking.
  37.  
  38.             Only standardFont bears any resemblance to what it
  39.             should.  symbolFont is still PostScript.
  40.  
  41.             The tables have been moved from this file to
  42.             ljtables.c
  43. */
  44.  
  45. #include "defs.h"
  46.  
  47. #if    defined(LJ) || defined(LK)
  48. #include "lj.h"
  49.  
  50. #define    MAXFONT    50
  51.  
  52. #ifndef    SVR3
  53. #ifndef    lint
  54. static char SCCSid[] = "@(#)lj.c: 1.7 Copyright 89/06/14 17:40:23 Chris Lewis";
  55. #endif
  56. #else
  57. #ident  "@(#)lj.c: 1.7 Copyright 89/06/14 17:40:23 Chris Lewis" /*(SVR3)*/
  58. #endif
  59.  
  60. #define    USED    1
  61. #define    BUILTIN 2
  62. struct ljFts {
  63.     char *troffName;
  64.     char *fontSeq;
  65.     char *ascName;
  66.     int     flags;
  67. } ljFts[MAXFONT+1];
  68.  
  69. struct ljFts *t2ljf[8];
  70.  
  71. /*    Used for characters not in Roman8 Character set */
  72. #define    NOPE    "\0374"
  73. ljPage() {
  74.     printf("\033&l0H");
  75.     pagePending = 1;
  76. }
  77.  
  78. static
  79. doPageStart(e) {
  80.     currentPage++;
  81.     pagePending = 0;
  82. }
  83.  
  84. static int lastFont = (-1), lastPoints = (-1);
  85. static
  86. putoct(s)
  87. char *s; {
  88.     int d;
  89.     if (strlen(s) < 3) {
  90.     fprintf(stderr, "%s: octal sequence in fonts.l[kj] bad\n", progname);
  91.     exit(1);
  92.     }
  93.     d = (*s - '0') * 64 + (*(s+1) - '0') * 8 + *(s+2) - '0';
  94.     putchar(d);
  95. }
  96.  
  97. ljSetFont(font, points)
  98. int font, points; {
  99.  
  100.     if (lastPoints != points || font != lastFont) {
  101.         register char *p;
  102. #ifdef    DOWNLOAD
  103.         if (!(ljFts[font].flags&(USED|BUILTIN))) {
  104.         char buf[512];
  105.         FILE *fontfile;
  106.         int count;
  107.         sprintf(buf, "%s/%s.%s.%d", LIBDIR, be->bename,
  108.             ljFts[font].troffName, points);
  109.         if ((fontfile = fopen(buf, "r")) == NULL) {
  110.             fprintf(stderr, "%s: Cannot open fontfile %s\n", progname,
  111.             buf);
  112.         } else {
  113.             while(0 > (count = fread(buf, sizeof(char), 512, fontfile)))
  114.             fwrite(buf, sizeof(char), count, stdout);
  115.             fclose(fontfile);
  116.         }
  117.         }
  118. #endif
  119.         ljFts[font].flags |= USED;
  120.         for (p = ljFts[font].fontSeq; *p; p++) {
  121.         if (*p == '\\') {
  122.             putoct(p+1);
  123.             p+=3;
  124.         } else
  125.             putchar(*p);
  126.         }
  127.         printf("\033(s%dV", points);
  128.         lastPoints = points;
  129.         lastFont = font;
  130.     }
  131.  
  132. }
  133.  
  134. ljChar(x, y, font, points, troffChar) 
  135. int x, y, font, points, troffChar; {
  136.     static double lasty = (-1);
  137.     register double nx = TROFF2LJX(x), ny = TROFF2LJY(y);
  138.     register struct troff2befont *rp;
  139.     register char *sequence = "a";
  140.     double xad, yad;
  141.     if (pagePending) {
  142.         lasty = lastFont = lastPoints = (-1);
  143.         doPageStart();
  144.     }
  145.  
  146.     DEBUGPRINTF("x,y=%d,%d; font=%d, points=%d, tc=%d\n",
  147.         x, y, font, points, troffChar);
  148.  
  149.     if (font == 3) {
  150.         rp = &be->besymfont[troffChar];
  151.     } else {
  152.         rp = &be->bestdfont[troffChar];
  153.     }
  154.  
  155.     switch(rp->t2b_font) {
  156.         /* Only fonts with "U" are subject to font translation */
  157.         case U: 
  158.         if (font == 3)
  159.             font = 0;    /* Special chars are Courier */
  160.         else {
  161.             DEBUGPRINTF("ljSetChar %d->%s (%s)\n", font, 
  162.             t2ljf[font]->troffName,
  163.             t2ljf[font]->ascName);
  164.             font = t2ljf[font] - ljFts;
  165.         }
  166.         break;
  167.         case S: 
  168.         font = 3;
  169.         break;
  170.         case D:
  171.         break;
  172.         default:
  173.         /* Typically used when the main fonts don't have the
  174.            character desired.  Eg: right-hand is in the
  175.            ZapfDingbats font */
  176.         font = rp->t2b_font;
  177.         break;
  178.     }
  179.  
  180.     sequence = rp->t2b_charseq;
  181.  
  182.     if (!sequence) {
  183.         fprintf(stderr, "No coding for %d\n", troffChar);
  184.         return;
  185.     }
  186.  
  187.     /*    We're committed now */
  188.  
  189.     points *= rp->t2b_scale;
  190.     xad = points * rp->t2b_xc;
  191.     yad = points * rp->t2b_yc;
  192.     ljSetFont(font, points);
  193.  
  194. /*    We won't output fractions */
  195. #define    XYS    "\033&a%.0fh%.0fV%s"
  196. #define    XS    "\033&a%.0fH%s"
  197.  
  198.     if (lasty != ny) {
  199.         printf(XYS, nx+xad, ny+yad, sequence);
  200.         lasty = ny;
  201.     } else
  202.         printf(XS, nx+xad, sequence);
  203. }
  204.  
  205. static
  206. loadfontdefs(f)
  207. FILE *f; {
  208.     struct ljFts *p = ljFts;
  209.     extern char *malloc();
  210.     int flags;
  211.     char rbuf[512], nbuf[512], ljbuf[512], seqbuf[512];
  212.     while(fgets(rbuf, sizeof(rbuf), f)) {
  213.     if (rbuf[0] == '#')
  214.         continue;
  215.     switch(sscanf(rbuf, "%s%s%s%d", nbuf, ljbuf, seqbuf, &flags)) {
  216.         default:
  217.         break;
  218.         case 4:
  219.         if (nbuf[0] == '#')
  220.             break;
  221.         if (p - ljFts >= MAXFONT) {
  222.             fprintf(stderr, "Too many font definitions in %s\n",
  223.             be->bename);
  224.             exit(1);
  225.         }
  226.         p->troffName = malloc(strlen(nbuf) + 1);
  227.         strcpy(p->troffName, nbuf);
  228.         p->ascName = malloc(strlen(ljbuf) + 1);
  229.         strcpy(p->ascName, ljbuf);
  230.         p->fontSeq = malloc(strlen(seqbuf) + 1);
  231.         strcpy(p->fontSeq, seqbuf);
  232.         p->flags = flags;
  233.         p++;
  234.     }
  235.     }
  236. #ifdef    DEBUG
  237.     for (p = ljFts; p->troffName; p++)
  238.     DEBUGPRINTF("%s -> %s, seq: %s\n", p->troffName, p->ascName, p->fontSeq);
  239. #endif
  240. }
  241.  
  242. ljProlog() {
  243.     extern char *getlogin(), *ctime();
  244.     char *buf2[15];
  245.     FILE *library;
  246.     int c;
  247.     long curtime;
  248.  
  249.     currentPage = 0;
  250.     pagePending = 1;
  251.  
  252.     for (c = 0; c < 8; c++)
  253.     t2ljf[c] = &ljFts[c];
  254.  
  255.     sprintf(buf2, "%s.%s", LJFONTS, be->bename);
  256.  
  257.     if ((library = fopen(buf2, "r")) == NULL) {
  258.     char buffer[512];
  259.     sprintf(buffer, "%s/%s", LIBDIR, buf2);
  260.     if ((library = fopen(buffer, "r")) == NULL) {
  261.         fprintf(stderr, "Cannot open %s font definitions %s\n",
  262.         LJFONTS, buffer);
  263.         exit(1);
  264.     }
  265.     }
  266.  
  267.     loadfontdefs(library);
  268.     fclose(library);
  269.  
  270.     sprintf(buf2, "%s.%s", LJLIB, be->bename);
  271.  
  272.     if ((library = fopen(buf2, "r")) == NULL) {
  273.     char buffer[512];
  274.     sprintf(buffer, "%s/%s", LIBDIR, buf2);
  275.     if ((library = fopen(buffer, "r")) == NULL) {
  276.         fprintf(stderr, "Cannot open %s\n", buffer);
  277.         exit(1);
  278.     }
  279.     }
  280.  
  281.     printf("\033E\033&k2G");    /* reset printer, set CR=CR,LF=CRLF,FF=CRFF */
  282.     printf("\033&l6d66p0o0e66f0L");/* letter size, portrait, no perf skip */
  283.     printf("\0339");        /* reset side margins */
  284.     printf("\033&a0r0C");    /* move cursor to 0,0 */
  285.  
  286.     ljXlate(library);
  287.     fclose(library);
  288. }
  289.  
  290. ljEpilog() {
  291. }
  292.  
  293. ljFontSel(from, to)
  294. char from, *to; {
  295. #ifdef    DEBUG
  296.     register int i;
  297.     register struct ljFts *p;
  298. #endif
  299.     DEBUGPRINTF("ljFontSel: %c -> %s\n", from, to);
  300.     if (from < '1' || from > '8') {
  301.     fprintf(stderr, "Bad arguments to ljFontSel: %c %s\n", from, to);
  302.     return;
  303.     }
  304.  
  305.     for (p = ljFts; p->troffName; p++)
  306.     if (strcmp(p->troffName, to) == 0) {
  307.         t2ljf[from - '1'] = p;
  308.         break;
  309.     }
  310.     if (!p->troffName) {
  311.     fprintf(stderr, "Could not translate font %c (%s)\n", from, to);
  312.     }
  313. #ifdef    DEBUG
  314.     for (i = 0; i < 8; i++)
  315.     DEBUGPRINTF("Font %d->%s\n", i+1, t2ljf[i]->ascName);
  316. #endif
  317. }
  318.  
  319. /*    Copy the library file to the standard output, stripping
  320.     %line\n
  321.     %%%<something> is a metadirective
  322.     and converting \nnn and \xnn as you go.
  323.     Strip out line termination.
  324. */
  325.  
  326. ljXlate(library)
  327. FILE *library; {
  328.     char buf[4];
  329.     int c, i;
  330.     c = getc(library);
  331.     while(!feof(library)) {
  332.  
  333.       nextchar:
  334.  
  335.     switch(c) {
  336.         case '%':
  337.         /* strip from percent sign to end of line */
  338.         /* If line is %%%<something> pass onto interp */
  339.         if (((c = getc(library)) == '%') &&
  340.             ((c = getc(library)) == '%')) {
  341.             char buf2[4];
  342.             sprintf(buf2, ".%s", be->bename);
  343.             fgets(buf, strlen(buf), library);
  344.             interp(buf, ljXlate, buf2);
  345.             break;
  346.         }
  347.         while ((c = getc(library)) != EOF && c != '\n');
  348.         break;
  349.         case '\n':    /* throw away real newlines. */
  350.         break;
  351.         case '\\':
  352.         c = getc(library);
  353.         if (c == 'x' || c == 'X') {
  354.             i = 0;
  355.             while(1) {
  356.             c = getc(library);
  357.  
  358.             if (c == EOF || !((c >= '0' && c <= '9') ||
  359.                       (c >= 'A' && c <= 'F') ||
  360.                       (c >= 'a' && c <= 'f')))
  361.                 goto nextchar;
  362.  
  363.             buf[i++] = c;
  364.             if (i == 2) {
  365.                 buf[i] = '\0';
  366.                 sscanf(buf, "%x", &i);
  367.                 putchar(i);
  368.                 i = 0;
  369.             }
  370.             }
  371.         } else {
  372.             buf[0] = c;
  373.             i = 1;
  374.             while(1) {
  375.             c = getc(library);
  376.             if (c == EOF || c < '0' || c > '7')
  377.                 goto nextchar;
  378.             buf[i++] = c;
  379.             if (i == 3) {
  380.                 buf[i] = '\0';
  381.                 sscanf(buf, "%o", &i);
  382.                 putchar(i);
  383.                 i = 0;
  384.             }
  385.             }
  386.         }
  387.         /* NOTREACHED */
  388.  
  389.         case ' ': case '\t':
  390.         break;
  391.  
  392.         case EOF:
  393.         fprintf(stderr, "%s: Unexpected eof on ljlib\n", progname);
  394.         break;
  395.  
  396.         default:
  397.         putchar(c);
  398.     }
  399.     c = getc(library);
  400.     }
  401. }
  402. #endif
  403.