home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / s / stex2-18.zip / SeeTeX / Iptex / imagen1.c < prev    next >
C/C++ Source or Header  |  1990-09-04  |  13KB  |  534 lines

  1. /*
  2.  * Copyright 1989 Dirk Grunwald
  3.  * 
  4.  * Permission to use, copy, modify, distribute, and sell this software
  5.  * and its documentation for any purpose is hereby granted without fee,
  6.  * provided that the above copyright notice appear in all copies and that
  7.  * both that copyright notice and this permission notice appear in
  8.  * supporting documentation, and that the name of Dirk Grunwald or M.I.T.
  9.  * not be used in advertising or publicity pertaining to distribution of
  10.  * the software without specific, written prior permission.  Dirk
  11.  * Grunwald and M.I.T. makes no representations about the suitability of
  12.  * this software for any purpose.  It is provided "as is" without express
  13.  * or implied warranty.
  14.  * 
  15.  * DIRK GRUNWALD AND M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  16.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17.  * FITNESS, IN NO EVENT SHALL M.I.T.  BE LIABLE FOR ANY SPECIAL, INDIRECT
  18.  * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  19.  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  20.  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  21.  * OR PERFORMANCE OF THIS SOFTWARE.
  22.  * 
  23.  * Author:
  24.  *     Dr. Dirk Grunwald
  25.  *     Dept. of Computer Science
  26.  *     Campus Box 430
  27.  *     Univ. of Colorado, Boulder
  28.  *     Boulder, CO 80309
  29.  * 
  30.  *     grunwald@colorado.edu
  31.  *     
  32.  */ 
  33.  
  34. #ifndef lint
  35. static char rcsid[] = "$Header: /usr/local/src/SeeTeX/Iptex/RCS/imagen1.c,v 1.11 90/09/04 08:59:54 grunwald Exp Locker: grunwald $";
  36. #endif
  37.  
  38. #include <stdio.h>
  39. #include <signal.h>
  40. #include "libtex/dvistuff.h"
  41. #include "./imagen.h"
  42. #include "./imPcodes.h"
  43.  
  44. extern int errno;    /* from libc */
  45.  
  46. /*
  47.  *    We use one of the per-glyph user flags to keep track of whether a
  48.  *    glyph has been loaded into the Imagen.
  49.  *
  50.  *    Font shrinkign uses USR0
  51.  */
  52. #define    GF_LOADED    GF_USR1
  53.  
  54. int    NextFamilyNumber;    /* next available Imagen glyph-family index */
  55.  
  56. int PageReversal = 0;
  57. int LandScape = 0;
  58. int DoPlots = 1;
  59. int Legal = 0;
  60. int Ledger = 0;
  61. int Verbose = 1;
  62. int ForcePrint = 0;
  63. int Debug;            /* -D => debug flag */
  64.  
  65. int    ImHH;            /* Imagen horizontal position */
  66. int    ImVV;            /* Imagen vertical position */
  67. int    ImFamily;        /* Imagen current-font number */
  68.  
  69. char    *PrintEngine;        /* e.g., canon, ricoh */
  70. struct fontinfo NoFont;        /* a fake font to help get things started */
  71.  
  72. char    *getenv(), *malloc();
  73. double atof();
  74.  
  75. /* Absolute value */
  76. #define ABS(n) ((n) >= 0 ? (n) : -(n))
  77.  
  78. /* Put a two-byte (word) value to the Imagen */
  79. #define putword(w) (putchar((w) >> 8), putchar(w))
  80.  
  81. char CenterWidth = 0;
  82. char CenterHeight = 0;
  83.  
  84. static struct OptionListStruct {
  85.     char *name;
  86.     char *def;
  87.     char *meaning;
  88. } OptionList[] = {
  89. {"-p", "false", "Select page reversal (print last page first)"},
  90. {"+p", "false", "Select no page reversal"},
  91. {"-l", "false", "Print in landscape mode (rotates fonts)"},
  92. {"-legal","false","Use legal (8 by 14.5) inch paper size"},
  93. {"-ledger","false","Use legal (11 by 17) inch paper size"},
  94. {"-lm <float>", "1.0", "Alias for ``-sm''"},
  95. {"-sm <float>", "1.0", "Set width of side margin, in inches"},
  96. {"-tm <float>", "1.0", "Set width of top margin, in inches"},
  97. {"-cwd", "false", "Center the document width in the page"},
  98. {"-cht", "false", "Center the document height in the page"},
  99. {"-v", "true", "Describe the document"},
  100. {"+v", "false", "Do not describe the document"},
  101. {"-force", "false", "Force the document to print printed, even with errors"},
  102. {"-m <integer>", "1000", "Select global document magnification"},
  103. {"-r <integer>", "300", "Set printer resolution in Dots Per Inch"},
  104. {"-d <integer>", "3", "Maximum drift from true DVI position"},
  105. {"-e <string> ", "imagen", "Select the type of printer"},
  106. {"-D", "false", "Turn on debugging information"},
  107. {"-P", "false", "Do not plot included figures"},
  108. {"-help", "", "This display"},
  109. {0, 0, 0}
  110. };
  111.  
  112. leave()
  113. {
  114.     dviFini();
  115.     exit(1);
  116. }
  117.  
  118. main(argc, argv)
  119.     int argc;
  120.     register char **argv;
  121. {
  122.     register int c;
  123.     int needHelp = 0;
  124.     double paperHeight;
  125.     double paperWidth;
  126.     int totalDviHeight;
  127.     int totalDviWidth;
  128.     
  129.     dviUserMag = 1000;
  130.     dviMaxDrift = DefaultMaxDrift;
  131.     dviDPI = DefaultDPI;
  132.     DVIFileName = 0;
  133.     dviPrintEngine = "canon";
  134.     
  135.     dviHHMargin = dviDPI;    /* stored as DEVs */
  136.     dviVVMargin = dviDPI;    /* stored as DEVs */
  137.     
  138. /*
  139.  *    The options processing has been switched from the getopt
  140.  *    routine to a possibly nastier version which allows
  141.  *    multi-letter options. This is needed for -sm and -tm
  142.  */
  143.     ProgName = argv[0];
  144.     argv++;
  145.     argc--;
  146.     while(argc > 0) {
  147.     if (**argv != '-' & **argv != '+') {
  148.         DVIFileName = *argv;
  149.     } else {
  150.         if (strcmp(*argv,"-d") == 0) {
  151.         argv++; argc--;
  152.         dviMaxDrift = atoi(*argv);
  153.         } else if (strcmp(*argv, "-e") == 0) {
  154.         argv++; argc--;
  155.         dviPrintEngine = *argv;
  156.         break;
  157.         } else if (strcmp(*argv, "-l") == 0) { /* landscape */
  158.         LandScape++;
  159.         dviFontRotation = ROT_RIGHT;
  160.         } else if (strcmp(*argv, "-m") == 0) { /* magnification */
  161.         argv++; argc--;
  162.         dviUserMag = atoi(*argv);
  163.         } else if (strcmp(*argv, "-p") == 0) { /* no page reversal */
  164.         PageReversal = 1;
  165.         } else if (strcmp(*argv, "+p") == 0) { /* no page reversal */
  166.         PageReversal = 0;
  167.         } else if (strcmp(*argv, "-r") == 0) { /* resolution */
  168.         argv++; argc--;
  169.         dviDPI = atoi(*argv);
  170.         } else if (strcmp(*argv, "-force") == 0) {
  171.         ForcePrint = 1;
  172.         } else if (strcmp(*argv, "-v") == 0) {
  173.         Verbose = 1;
  174.         } else if (strcmp(*argv, "+v") == 0) {
  175.         Verbose = 0;
  176.         } else if (strcmp(*argv, "-D") == 0) { /* debug */
  177.         Debug++;
  178.         } else if (strcmp(*argv, "-P") == 0) { /* plot inclusion */
  179.         DoPlots=0;
  180.         } else if (strcmp(*argv, "-tm") == 0){ /* top margin, inches */
  181.         argv++; argc--;
  182.         dviVVMargin = atof(*argv) * dviDPI;
  183.         } else if (strcmp(*argv, "-sm") == 0 || strcmp(*argv, "-lm") == 0){
  184.         argv++; argc--;
  185.         dviHHMargin = atof(*argv) * dviDPI;
  186.         } else if (strcmp(*argv, "-cwd") == 0){
  187.         CenterWidth = 1;
  188.         } else if (strcmp(*argv, "-cht") == 0){
  189.         CenterHeight = 1;
  190.         } else if (strcmp(*argv, "-legal") == 0){
  191.         Legal = 1;
  192.         } else if (strcmp(*argv, "-ledger") == 0){
  193.         Ledger = 1;
  194.         } else {
  195.         needHelp = 1;
  196.         }
  197.     }
  198.     
  199.     argv++; argc--;
  200.     }
  201.  
  202.     if (Legal && Ledger) {
  203.     fprintf(stderr, "%s: choose only one of -legal and -ledger\n",
  204.         ProgName);
  205.     exit(1);
  206.     }
  207.     
  208.     if (needHelp) {
  209.     int i;
  210.     fprintf(stderr,"Usage: %s [options] file[.dvi]\n",
  211.         ProgName);
  212.     fprintf(stderr, "%-15s| %-7s| %s\n", "Option", "Default", "Meaning");
  213.     fprintf(stderr, "-------------------------------------------------\n");
  214.     for (i = 0; OptionList[i].name != 0; i++) {
  215.         fprintf(stderr, "%-15s| %-7s| %s\n",
  216.             OptionList[i].name,
  217.             OptionList[i].def,
  218.             OptionList[i].meaning);
  219.     }
  220.     fprintf(stderr,"\nArguments must be provided. The default value is\n");
  221.     fprintf(stderr,"used if the option is not specified\n");
  222.     (void) fflush(stderr);
  223.     exit(1);
  224.     }
  225.     
  226.     if (dviInit()) {
  227.     if (DVIFileName == 0) {
  228.         error(1, errno, "Error openning stdin");
  229.     } else {
  230.         error(1, errno, "Error openning %s", DVIFileName);
  231.     }
  232.     leave(1);
  233.     }
  234.  
  235. /*
  236.  *    Set up signal handlers to clean up.
  237.  */
  238.     signal(SIGHUP, leave);
  239.     signal(SIGQUIT, leave);
  240.     signal(SIGINT, leave);
  241.     signal(SIGTERM, leave);
  242.  
  243.     if (Legal) {
  244.     paperHeight = 14;
  245.     paperWidth = 8.5;
  246.     } else if (Ledger) {
  247.     paperHeight = 17;
  248.     paperWidth = 11;
  249.     } else {
  250.     paperHeight = 11;
  251.     paperWidth = 8.5;
  252.     }
  253.  
  254.     if (LandScape) {
  255.     double x = paperHeight;
  256.     paperHeight = paperWidth;
  257.     paperWidth = x;
  258.     }
  259.  
  260.     if (CenterWidth) {
  261.     int margin = (paperWidth * dviDPI) - (dviWidestPage);
  262.     if (margin > 0) {
  263.         dviHHMargin = margin / 2;
  264.     }
  265.     }
  266.  
  267.     if (CenterHeight) {
  268.     int margin = (paperHeight * dviDPI) - (dviTallestPage);
  269.     if (margin > 0) {
  270.         dviVVMargin = margin / 2;
  271.     }
  272.     }
  273.  
  274. /*
  275.  *    Margins only occur on *one* side of the paper.
  276.  */
  277.  
  278.     totalDviWidth  = dviWidestPage + 1 * dviHHMargin;
  279.     totalDviHeight = dviTallestPage + 1 * dviVVMargin;
  280.  
  281. /*
  282.  *    Tell a story about the document
  283.  */
  284.     if (Verbose) {
  285.     fprintf(stderr,"Without margins, your document is %4.2f inches wide and %4.2f inches tall\n",
  286.         (float) dviWidestPage / (float) dviDPI,
  287.         (float) dviTallestPage / (float) dviDPI);
  288.     fprintf(stderr,"You have margins of %4.2f inches on the left and %4.2f on the top\n",
  289.         (float) dviHHMargin / (float) dviDPI,
  290.         (float) dviVVMargin / (float) dviDPI);
  291.     }
  292.  
  293.     if (totalDviHeight > (paperHeight * dviDPI) ||
  294.     totalDviWidth > (paperWidth * dviDPI) ) {
  295.         fprintf(stderr,"WARNING: document (with these margins) bigger than paper (%4.2fw by %4.2fh)\n",
  296.             paperWidth, paperHeight);
  297.         if (!ForcePrint) {
  298.         fprintf(stderr,"WARNING: rerun with -force\n");
  299.         leave(1);
  300.         }
  301.     }
  302. /*
  303.  *    Prepare @document commands for Imagen
  304.  */
  305.  
  306.     printf("@document(language imPRESS, name \"%s\"", DVIFileName);
  307.     if (Legal) {
  308.     printf(",paper legal, inputbin legal");
  309.     }
  310.     if (Ledger) {
  311.     printf(",paper ledger, inputbin ledger");
  312.     }
  313.     printf(")");
  314.     
  315.     if (LandScape) {
  316.     putchar(imP_SetHVSystem);
  317.     putchar(0x55);    /* origin=ulc, h:v=90, h:x=90 */
  318.     putchar(imP_SetAdvDirs);
  319.     putchar(0);    /* main=0 (degrees), secondary=90 */
  320.     }
  321.  
  322.     if (PageReversal) {
  323.     int i;
  324.     for (i = dviTotalPages - 1; i >= 0; i--) {
  325.         BeginPage(i);
  326.     }
  327.     } else {
  328.     int i;
  329.     for (i = 0; i < dviTotalPages; i++) {
  330.         BeginPage(i);
  331.     }
  332.     }
  333.  
  334.     if (Verbose) {
  335.     fprintf(stderr,"\n");
  336.     }
  337.  
  338.     putchar(imP_EOF);
  339.  
  340.     dviFini();
  341.     exit(0);
  342. }
  343.  
  344. /*
  345.  * Start a page (process a DVI_BOP).
  346.  */
  347. BeginPage(pageNumber)
  348. int pageNumber;
  349. {
  350.     putchar(imP_Page);
  351.     ImHH = 0;
  352.     ImVV = 0;
  353.     ImFamily = -1; /* imP_SetFamily command */
  354.     dviPreparePage(pageNumber);
  355.     if (Verbose) {
  356.     int i;
  357.     (void) fprintf(stderr, "[%ld", dviCount[0][dviCurrentPage]);
  358.     for (i = 1; i < DVI_COUNT; i++) {
  359.         long v = dviCount[i][dviCurrentPage];
  360.         if (v == 0) {
  361.         break;
  362.         }
  363.         fprintf(stderr,".%ld", v);
  364.     }
  365.     fprintf(stderr, "]");
  366.     (void) fflush(stderr);
  367.     }
  368.     putchar(imP_EndPage);
  369. }
  370.  
  371. DviFont *
  372. applicationNewFont(f, key)
  373. DviFont *f;
  374. int key;
  375. {
  376.     if (key < 0 || key > MAX_FONTFAMILY) {
  377.     fprintf(stderr,"[%s] bogus key in Newfont = %d\n",
  378.         ProgName, key);
  379.     leave();
  380.     }
  381.     return(f);
  382. }
  383.  
  384. void
  385. applicationResetFont()
  386. {
  387. }
  388.  
  389. void
  390. applicationPutChar(hh, vv, charCode)
  391.     int hh;
  392.     int vv;
  393.     int charCode;
  394. {
  395.     register struct glyph *g;
  396.     int x,y;
  397.     int key;
  398.  
  399.     key = dviCurrentFont -> family;
  400.     g = GLYPH(dviCurrentFont -> f, charCode);
  401.     if ((g->g_flags & GF_LOADED) == 0) {
  402.     ImDownLoadGlyph(charCode, g);
  403.     }
  404.     /* BEGIN INLINE EXPANSION OF ImSetPosition */
  405.     if (ImHH != hh) {
  406.     if (ImHH == hh - 1)
  407.         putchar(imP_Forw);
  408.     else if (ImHH == hh + 1)
  409.         putchar(imP_Backw);
  410.     else {
  411.         putchar(imP_SetHAbs);
  412.         putword(hh);
  413.     }
  414.     ImHH = hh;
  415.     }
  416.     if (ImVV != vv) {
  417.     putchar(imP_SetVAbs);
  418.     putword(vv);
  419.     ImVV = vv;
  420.     }
  421.     /* END INLINE EXPANSION OF ImSetPosition */
  422.  
  423.     if (ImFamily != dviCurrentFont->family) {
  424.     putchar(imP_SetFamily);
  425.     putchar(dviCurrentFont->family);
  426.     ImFamily = dviCurrentFont->family;
  427.     }
  428.     putchar(charCode);
  429.     ImHH += g->g_pixwidth;
  430. }
  431.  
  432. void
  433. applicationDoSpecial(cp)
  434. char *cp;
  435. {
  436.     ImSetPosition(dviHH, dviVV);
  437.     newDoSpecial(cp);
  438. }
  439.  
  440. /*
  441.  * Draw a rule at the current (hh,vv) position. 
  442.  */
  443. void
  444. applicationSetRule(hh, vv, h, w)
  445. int hh, vv;
  446. int h, w;
  447. {
  448.     /* put the rule out */
  449.     if (ImHH != hh || ImVV != vv)
  450.     ImSetPosition(hh, vv);
  451.     putchar(imP_Rule);
  452.     putword(w);
  453.     putword(h);
  454.     putword(-h + 1);
  455. }
  456.  
  457. /*
  458. * Download the character c/g in the current font.
  459. */
  460. ImDownLoadGlyph(c, g)
  461.     int c;
  462.     register struct glyph *g;
  463. {
  464.     register char *p;
  465.     register int i, j, w;
  466.     
  467.     g->g_pixwidth = fromSP(g->g_tfmwidth);
  468.     g->g_flags |= GF_LOADED;
  469.     if (!HASRASTER(g))    /* never load dull glyphs */
  470.     return;
  471.     
  472.     if (dviFontRotation == ROT_NORM) {
  473.     w = 0;
  474.     p = RASTER(g, dviCurrentFont->f, ROT_NORM);
  475.     } else {
  476.     w = 1 << 14;
  477.     p = RASTER(g, dviCurrentFont->f, ROT_RIGHT);
  478.     }
  479.     
  480.     w |= (dviCurrentFont->family << 7) | c;
  481.     
  482.     /* Define the character */
  483.     putchar(imP_DefGlyph);    /* a.k.a. BGLY */
  484.     putword(w);        /* rotation, family, member */
  485.     putword(g->g_pixwidth);    /* advance */
  486.     putword(g->g_width);    /* width */
  487.     putword(g->g_xorigin);    /* left offset */
  488.     putword(g->g_height);    /* height */
  489.     putword(g->g_yorigin);    /* top-offset */
  490.     
  491. /*
  492.  * Now put out the bitmap
  493.  */
  494.     w = (g->g_width + 7) >> 3;
  495.     for (i = g->g_height; --i >= 0;){
  496.     for (j = w; --j >= 0;) {
  497.         (void) putchar(*p++);
  498.     }
  499.     }
  500.  
  501. #ifdef UNDEF    
  502.     if (g->g_raster) {    /* XXX */
  503.     free(g->g_raster);
  504.     g->g_raster = NULL;
  505.     }
  506. #endif
  507.     
  508. }
  509.  
  510. /*
  511.  * Set the Imagen's h & v positions.  It is currently at ImHH, ImVV.
  512.  */
  513. ImSetPosition(h, v)
  514.     register int h, v;
  515. {
  516.     
  517.     if (ImHH != h) {
  518.     if (ImHH == h - 1)
  519.         putchar(imP_Forw);
  520.     else if (ImHH == h + 1)
  521.         putchar(imP_Backw);
  522.     else {
  523.         putchar(imP_SetHAbs);
  524.         putword(h);
  525.     }
  526.     ImHH = h;
  527.     }
  528.     if (ImVV != v) {
  529.     putchar(imP_SetVAbs);
  530.     putword(v);
  531.     ImVV = v;
  532.     }
  533. }
  534.