home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume14 / cat2deskjet / part02 / lcat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-30  |  12.4 KB  |  489 lines

  1. /*****************************************************************
  2.  *
  3.  *   Copyright 1985. Chris Lewis
  4.  *
  5.  *   Module          : lcat.c 1.5
  6.  *   Date submitted  : 86/01/21 13:23:21
  7.  *   Author          : Chris Lewis
  8.  *   Origin          : Permission to copy and further distribute is 
  9.  *                freely given provided this copyright notice remains 
  10.  *               intact and that this software is not sold for profit.
  11.  *   Description     : Driver for troff WANG/CAT to HP laserjet filter.
  12.  *
  13.  *   Modifications (by vp@cui.unige.ch):
  14.  *
  15.  *    - modications for compatibility with BSD vfonts
  16.  *    - modifications for porting to MS-LOSS
  17.  *    - converted to use soft fonts instead of graphics mode
  18.  *    - removed multiple resolutions option since with soft fonts
  19.  *      you don't get to chose.
  20.  *
  21. ******************************************************************/
  22.  
  23. #ifndef lint
  24. static char SrcId[] = "@(#)lcat.c:1.5";
  25. #endif
  26.  
  27. #include <stdio.h>
  28. #include <ctype.h>
  29. #include <string.h>
  30. extern void terminate();
  31.  
  32. #define    ESC    0x80
  33. #define    FLASH    0x00
  34. #define    CONTROL    0x40
  35. #define    LEAD    0x60
  36. #define    SIZE    0x50
  37.  
  38. #define    DOWN    0
  39. #define    UP    1
  40. #define    LOWER    2
  41. #define    UPPER    3
  42. #define    FORWARD    4
  43. #define    BACKWARD 5
  44.  
  45. #ifdef UNIX
  46. FILE    *inFile = stdin;
  47. FILE    *outFile = stdout;
  48. #else
  49. FILE    *inFile = (FILE *) NULL;
  50. FILE    *outFile = (FILE *) NULL;
  51. #endif
  52. FILE    *diagFile = (FILE *) NULL;
  53. #define    DEBUGPRINTF    if (diagFile) fprintf
  54.  
  55.  
  56. /*
  57.  * note: the BSD4.3 vfonts are really too big at 75 dpi, so we have to
  58.  * always print them at a higher resolution (in this case 300 dpi).
  59.  *
  60.  * Unfortunately at this resolution they are too small, so for a given
  61.  * pointsize request we have to select a larger pointsize.
  62.  *
  63.  * We try to select the one closest to the requested size plus 4 points.
  64.  */
  65. #ifdef ORIG
  66. char ptab[16] = { 7, 8, 10, 11, 12, 14, 18, 9, 6, 16, 20, 22, 24, 28, 36, 72};
  67. char ptab[16] = { 10, 12, 14, 14, 16, 22, 22, 12, 10, 22, 24, 24, 28, 28, 36, 72 };
  68. #else
  69. char ptab[16] = { 11, 12, 16, 16, 18, 22, 28, 14, 9, 24, 28, 36, 36, 36, 36, 36};
  70. #endif
  71. int    points;
  72. int    vertChanged = 0;
  73. int    quality    = 1;
  74. int lcat;
  75.  
  76.  
  77. /*    Scale factors:
  78.         (td/ld) * (lu / tu)
  79.         Where:
  80.             td: troff dimension in inches
  81.             ld: laserjet dimension in inches
  82.             lu: laserjet precision/inch
  83.             tu: troff precision/inch
  84.  
  85.         td = 6.5 (width), 11 (length)
  86.         tu = 432
  87.         ld = 6.5 (width), 10 (length)
  88.         lu = 720
  89. */
  90.  
  91. #define    XSF    1.6666666    /* X Scale factor (troff to laserjet units) */
  92. #define    YSF    1.5151515    /* Y Scale factor (troff to laserjet units) */
  93.  
  94. long    xpos, oldypos = -9999, ypos = -153;
  95.  
  96. char *words[] = {
  97.     "down", "up", "lower", "upper", "forward", "backwards"
  98.     };
  99.  
  100. static char    fontFamily[BUFSIZ];
  101. static char    djfontFamily[BUFSIZ];
  102. char    *fontName;
  103. #ifdef UNIX
  104. char    *fontLib = "/usr1/tmp/vfonts/";
  105. #else
  106. char    *fontLib = "/usr/vfonts/";
  107. #endif
  108.  
  109. #define    CTOINT(val,sig)    ((~c)&sig)
  110.  
  111. #define    UNITS    432
  112. #define    FONT4        /* 4 Font device */
  113.  
  114. /*
  115.  * calcfont -- calculate new font depending on the rail, mag and tilt options
  116.  */
  117. #ifdef    FONT4
  118. #define    calcfont    ((mag == UPPER)<<1)|((rail == UPPER))
  119. #else
  120. #define    calcfont    ((mag == UPPER)<<2)|((rail == UPPER)<<1)|(tilt==DOWN)
  121. #endif
  122.  
  123. main(argc, argv)
  124. int    argc;
  125. char    **argv; {
  126.     register int nc, c;
  127.     register char *rp;
  128.     register int i,j;
  129.     register int decipoints;
  130.     register int units;
  131.     register int font, rail, mag, tilt, half, escape, lead;
  132.     char* ofile;
  133.     char* infile;
  134.  
  135.     lead=half=rail=mag=tilt=font=0;
  136.     
  137. #ifdef UNIX
  138.     /* under UNIX default input and output files are the
  139.      * standard input and output respectively.
  140.      * Under MS-LOSS we have to use explicit files because of I/O
  141.      * redirection probs.
  142.      */
  143.     infile = NULL;
  144.     ofile = NULL;
  145.     fontName = "times.";
  146. #else
  147.     infile = "/tmp/out";
  148.     ofile = "prn:";
  149.     /* under MSLOSS (the system that likes to say no)
  150.        filenames can only have one dot, so we use a '-' instead */
  151.     fontName = "times-";
  152. #endif
  153.     quality = 1;
  154.     lcat = (argv[0][strlen(argv[0])-4] == 'l');
  155.     argv++;
  156.     argc--;
  157.     if (argc > 0)    /* process parameters */
  158.     {
  159.         while (argc > 0 && **argv == '-')
  160.         {
  161.             switch (*(*argv+1)) {
  162.             case 'D':    /* diagnostic output */
  163.                 diagFile = fopen("diag.txt", "w");
  164.                 if (!diagFile)
  165.                 {
  166.                     fprintf(stderr, "Could not open diagnostics file\n");
  167.                     exit(1);
  168.                 }
  169.                 argv++;
  170.                 argc--;
  171.                 break;
  172.             case 'f':    /* select different font family */
  173.                 fontName = *++argv;
  174.                 argv++;
  175.                 argc -= 2;
  176.                 break;
  177.             case 'O':    /* specify output file */
  178.                 ofile = *++argv;
  179.                 argv++;
  180.                 argc -= 2;
  181.                 break;
  182.             case 'l':    /* select low (draft) quality */
  183.                 /* this option is valid ONLY for the lcat version */
  184.                 quality = 2;
  185.                 argv++;
  186.                 argc -= 1;
  187.                 if (lcat)
  188.                     break;
  189.                 /* otherwise fall through to the error code */
  190.             default:
  191.                 usage();
  192.                 exit(1);
  193.             }
  194.         }
  195.         if (argc > 0)
  196.         {
  197.             infile = *argv;
  198.             argv++;
  199.             argc--;
  200.         }
  201.     }
  202.     
  203.  
  204.     /* if not absolute path, prepend vfont directory path */
  205. #ifdef UNIX
  206.     if (fontName[0] == '/' || fontName[1] == ':')
  207.         sprintf(fontFamily, "%s", fontName);
  208.     else
  209.         sprintf(fontFamily, "%s%s", fontLib, fontName);
  210. #else
  211.     if (fontName[0] == '/' || fontName[1] == ':')
  212.     {
  213.         char *vp;
  214.         sprintf(fontFamily, "%s", fontName);
  215.         /* isolate path to font directory */
  216.         vp = strrchr(fontName, '/');
  217.         *vp = '\0';
  218.         sprintf(djfontFamily, "%s/djfonts", fontName);
  219.         ft_init(djfontFamily);
  220.         sprintf(djfontFamily, "%s/djfonts/%s", fontName, vp+1);
  221.     } else {
  222.         sprintf(fontFamily, "%s%s", fontLib, fontName);
  223.         sprintf(djfontFamily, "%sdjfonts", fontLib);
  224.         ft_init(djfontFamily);
  225.         sprintf(djfontFamily, "%sdjfonts/%s", fontLib, fontName);
  226.     }
  227. #endif
  228.  
  229.     DEBUGPRINTF(diagFile, "font family: %s\n", fontFamily);
  230.     if (ofile != NULL)
  231.         if ((outFile = fopen(ofile, "wb")) == NULL)
  232.         {
  233.             fprintf(stderr, "Couldn't open output file %s\n", ofile);
  234.             exit(1);
  235.         }
  236.     if (infile != NULL)
  237.         if ((inFile = fopen(infile, "rb")) == NULL)
  238.         {
  239.             fprintf(stderr,
  240.                 "Couldn't open input file %s\n", infile);
  241.             exit(1);
  242.         }
  243.     vf_init(quality, fontFamily, djfontFamily);
  244.     while (!feof(inFile)) {
  245.         c = getc(inFile);
  246.         switch(c) {
  247.         case 0x00:
  248.             DEBUGPRINTF(diagFile, "NOP\n");
  249.             break;
  250.         /* Flash (print character) codes */
  251.         case 0x01: case 0x02: case 0x03: case 0x04: 
  252.         case 0x05: case 0x06: case 0x07: case 0x08: 
  253.         case 0x09: case 0x0a: case 0x0b: case 0x0c: 
  254.         case 0x0d: case 0x0e: case 0x0f: case 0x10: 
  255.         case 0x11: case 0x12: case 0x13: case 0x14:
  256.         case 0x15: case 0x16: case 0x17: case 0x18: 
  257.         case 0x19: case 0x1a: case 0x1b: case 0x1c: 
  258.         case 0x1d: case 0x1e: case 0x1f: case 0x20: 
  259.         case 0x21: case 0x22: case 0x23: case 0x24: 
  260.         case 0x25: case 0x26: case 0x27: case 0x28:
  261.         case 0x29: case 0x2a: case 0x2b: case 0x2c: 
  262.         case 0x2d: case 0x2e: case 0x2f: case 0x30: 
  263.         case 0x31: case 0x32: case 0x33: case 0x34: 
  264.         case 0x35: case 0x36: case 0x37: case 0x38: 
  265.         case 0x39: case 0x3a: case 0x3b: case 0x3c:
  266.         case 0x3d: case 0x3e: case 0x3f:
  267.             /* This is terribly kludgey:
  268.                 In 432 units per inch, 4752 is 11 inches.
  269.                 When we go beyond this, we subtract 4752
  270.                 and ignore anything printed on this line.
  271.             */
  272.             while (ypos >= 4752) {
  273.                 ypos -= 4752;
  274.                 oldypos = -9999;
  275.                 DEBUGPRINTF(diagFile, "Page break\n", 0, 0);
  276.                 vf_newpage();
  277.             }
  278.             if (ypos <= 20) {
  279.                 DEBUGPRINTF(diagFile, "Ignoring: %d, %d\n", xpos, ypos);
  280.                 break; /* ignore anything less than this
  281.                     from the beginning of a page */
  282.             }
  283.             c &= 0x3f;
  284.             DEBUGPRINTF(diagFile, "Flash %02d %s font %d\n", c&0x3f, 
  285.                 words[half], font);
  286. /*
  287. printf("font(%d)=%s,rail(%d)=%s,mag(%d)=%s,tilt(%d)=%s,half(%d)=%s\n",
  288.     font, words[font], rail, words[rail], mag, words[mag],
  289.     tilt, words[tilt], half, words[half]);
  290. */
  291.             DEBUGPRINTF(diagFile, "x,y=%ld,%ld; font=%d; rail=%s; mag=%s; tilt=%s; half=%s\n",
  292.                 xpos,ypos,font+1,words[rail],words[mag],words[tilt],
  293.                 words[half]);
  294.             /*    Find the C/A/T code */
  295.             if (half == UPPER) {
  296.                 if (c > 46) {
  297.                     fprintf(stderr, "Illegal upper flash: %d\n", c);
  298.                     terminate(1);
  299.                 }
  300.                 nc = c + 62;
  301.             } else
  302.                 nc = c - 1;
  303.  
  304.             /*
  305.              * the new version of flashrast needs to know
  306.              * where the letter will be placed.  Thus we
  307.              * call a routine in newfonts.c that can then save
  308.              * these numbers.
  309.              */
  310.             vf_move((long) (xpos*XSF), (long) (ypos*YSF));
  311.             oldypos = ypos;
  312.             vertChanged = 0;
  313.             flashrast(nc, points, font);
  314.             vertChanged = 1;
  315.             break;
  316.         /* Control codes */
  317.         case 0x40:
  318.             DEBUGPRINTF(diagFile, "Initialize\n");
  319.             xpos = 0;
  320.             ypos = -153;
  321.             escape = FORWARD;
  322.             lead = FORWARD;
  323.             half = LOWER;
  324.             rail = LOWER;
  325.             mag = LOWER;
  326.             tilt = DOWN;
  327.             font = calcfont;
  328.             break;
  329.         case 0x41:
  330.             DEBUGPRINTF(diagFile, "Rail lower\n");
  331.             rail = LOWER;
  332.             font = calcfont;
  333.             break;
  334.         case 0x42:
  335.             DEBUGPRINTF(diagFile, "Rail upper\n");
  336.             rail = UPPER;
  337.             font = calcfont;
  338.             break;
  339.         case 0x43:
  340.             DEBUGPRINTF(diagFile, "Mag upper\n");
  341.             mag = UPPER;
  342.             font = calcfont;
  343.             break;
  344.         case 0x44:
  345.             DEBUGPRINTF(diagFile, "Mag lower\n");
  346.             mag = LOWER;
  347.             font = calcfont;
  348.             break;
  349.         case 0x45:
  350.             DEBUGPRINTF(diagFile, "half lower\n");
  351.             half = LOWER;
  352.             break;
  353.         case 0x46:
  354.             DEBUGPRINTF(diagFile, "half upper\n");
  355.             half = UPPER;
  356.             break;
  357.         case 0x47:
  358.             DEBUGPRINTF(diagFile, "Escape forward\n");
  359.             escape = FORWARD;
  360.             break;
  361.         case 0x48:
  362.             DEBUGPRINTF(diagFile, "Escape backward\n");
  363.             escape = BACKWARD;
  364.             break;
  365.         case 0x49:
  366.             DEBUGPRINTF(diagFile, "STOP\n");
  367.             break;
  368.         case 0x4a:
  369.             DEBUGPRINTF(diagFile, "Lead forward\n");
  370.             lead = FORWARD;
  371.             break;
  372.         case 0x4b:
  373.             DEBUGPRINTF(diagFile, "Software cut!\n");
  374.             break;
  375.         case 0x4c:
  376.             DEBUGPRINTF(diagFile, "Lead backward\n");
  377.             lead = BACKWARD;
  378.             break;
  379.         case 0x4d:
  380.             DEBUGPRINTF(diagFile, "UNKNOWN CONTROL CODE!\n");
  381.             terminate(0);
  382.         case 0x4e:
  383.             DEBUGPRINTF(diagFile, "Tilt up\n");
  384.             tilt = UP;
  385.             font = calcfont;
  386.             break;
  387.         case 0x4f:
  388.             DEBUGPRINTF(diagFile, "Tilt down\n");
  389.             tilt = DOWN;
  390.             font = calcfont;
  391.             break;
  392.  
  393.         /* Size changes */
  394.         case 0x50: case 0x51: case 0x52: case 0x53:
  395.         case 0x54: case 0x55: case 0x56: case 0x57:
  396.         case 0x58: case 0x59: case 0x5a: case 0x5b:
  397.         case 0x5c: case 0x5d: case 0x5e: case 0x5f:
  398.             DEBUGPRINTF(diagFile, "Size change %02x\n", c&0xf);
  399.             points = ptab[c&0xf];
  400.             break;
  401.         /* Lead (vertical motion) codes */
  402.         case 0x60: case 0x61: case 0x62: case 0x63:
  403.         case 0x64: case 0x65: case 0x66: case 0x67:
  404.         case 0x68: case 0x69: case 0x6a: case 0x6b:
  405.         case 0x6c: case 0x6d: case 0x6e: case 0x6f:
  406.         case 0x70: case 0x71: case 0x72: case 0x73:
  407.         case 0x74: case 0x75: case 0x76: case 0x77:
  408.         case 0x78: case 0x79: case 0x7a: case 0x7b:
  409.         case 0x7c: case 0x7d: case 0x7e: case 0x7f:
  410.  
  411.             DEBUGPRINTF(diagFile, "Lead(vertical) %02x\n", c&0x1f);
  412.             units = CTOINT(c,0x1f);
  413.             if (lead == FORWARD) {
  414.                 ypos += 3*units;
  415.             } else {
  416.                 ypos -= 3*units;
  417.             }
  418.             break;
  419.         /* Escape (horizontal motion) codes */
  420.         case 0x80: case 0x81: case 0x82: case 0x83:
  421.         case 0x84: case 0x85: case 0x86: case 0x87:
  422.         case 0x88: case 0x89: case 0x8a: case 0x8b:
  423.         case 0x8c: case 0x8d: case 0x8e: case 0x8f:
  424.         case 0x90: case 0x91: case 0x92: case 0x93:
  425.         case 0x94: case 0x95: case 0x96: case 0x97:
  426.         case 0x98: case 0x99: case 0x9a: case 0x9b:
  427.         case 0x9c: case 0x9d: case 0x9e: case 0x9f:
  428.         case 0xa0: case 0xa1: case 0xa2: case 0xa3:
  429.         case 0xa4: case 0xa5: case 0xa6: case 0xa7:
  430.         case 0xa8: case 0xa9: case 0xaa: case 0xab:
  431.         case 0xac: case 0xad: case 0xae: case 0xaf:
  432.         case 0xb0: case 0xb1: case 0xb2: case 0xb3:
  433.         case 0xb4: case 0xb5: case 0xb6: case 0xb7:
  434.         case 0xb8: case 0xb9: case 0xba: case 0xbb:
  435.         case 0xbc: case 0xbd: case 0xbe: case 0xbf:
  436.         case 0xc0: case 0xc1: case 0xc2: case 0xc3:
  437.         case 0xc4: case 0xc5: case 0xc6: case 0xc7:
  438.         case 0xc8: case 0xc9: case 0xca: case 0xcb:
  439.         case 0xcc: case 0xcd: case 0xce: case 0xcf:
  440.         case 0xd0: case 0xd1: case 0xd2: case 0xd3:
  441.         case 0xd4: case 0xd5: case 0xd6: case 0xd7:
  442.         case 0xd8: case 0xd9: case 0xda: case 0xdb:
  443.         case 0xdc: case 0xdd: case 0xde: case 0xdf:
  444.         case 0xe0: case 0xe1: case 0xe2: case 0xe3:
  445.         case 0xe4: case 0xe5: case 0xe6: case 0xe7:
  446.         case 0xe8: case 0xe9: case 0xea: case 0xeb:
  447.         case 0xec: case 0xed: case 0xee: case 0xef:
  448.         case 0xf0: case 0xf1: case 0xf2: case 0xf3:
  449.         case 0xf4: case 0xf5: case 0xf6: case 0xf7:
  450.         case 0xf8: case 0xf9: case 0xfa: case 0xfb:
  451.         case 0xfc: case 0xfd: case 0xfe:
  452.  
  453.             units = CTOINT(c,0x7f);
  454.             if (escape == FORWARD) {
  455.                 xpos += units;
  456.             } else {
  457.                 xpos -= units;
  458.             }
  459.             DEBUGPRINTF(diagFile, "ESC (hor): %02x\n", c&0x7f);
  460.             break;
  461.  
  462.         case 0xff:
  463.             DEBUGPRINTF(diagFile, "Illegal: %02x\n", c);
  464.             break;
  465.         }
  466.     }
  467.     vf_newpage();
  468.     terminate(0);
  469. }
  470.  
  471. void terminate(xx)
  472. int xx;
  473. {
  474. #ifndef UNIX
  475.     ft_close();
  476. #endif
  477.     exit(xx);
  478. }
  479.  
  480.  
  481. usage()
  482. {
  483.     if (lcat)
  484.         fprintf(stderr, "usage: lcat [-f fontname] [-l] [-O file] [file]\n");
  485.     else
  486.         fprintf(stderr, "usage: vcat [-f fontname] [-O file] [file]\n");
  487. }
  488.  
  489.