home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / PRINTING / SHOWGL10.ZIP / HPGL2.C < prev    next >
C/C++ Source or Header  |  1991-08-29  |  14KB  |  549 lines

  1. #pragma linesize(132)    /* listing linewidth = 132 */
  2.  
  3. /* this file contains the following functions:
  4.  
  5.     begin_plot ()
  6.     define_path ()
  7.     label_origin ()
  8.     line_pattern ()
  9.     page_adv ()
  10.     set_csize ()
  11.     calc_csize ()
  12.     set_slant ()
  13.     extra_space ()
  14.     char_plot ()
  15.     label_graph ()
  16.     symbol_mark ()
  17.     label_term ()
  18.     label_dir ()
  19. */
  20.  
  21. #include <stdio.h>
  22. #include <math.h>
  23. #include "hpgl.h"
  24. #include "graph.h"
  25.  
  26. extern struct csizes cs;
  27. extern struct cplot cp;
  28.  
  29. extern int x_mirror, y_mirror;
  30. extern double p1x, p2x, p1y, p2y;
  31. extern unsigned endlabel;
  32.  
  33. static char copyright[] = "Copyright 1991, Robert C. Becker, Lantern Systems";
  34. static unsigned char label_bfr[LABEL_BFR];
  35. static double es_x, es_y;
  36.  
  37. /*--------------------------------------*/
  38.  
  39. void label_origin (FILE * infile)
  40.     {
  41.     double x;
  42.     int l;
  43.  
  44.     if (!get_val (infile, &x) )
  45.         {
  46.         cp.lorg = LORG_DEFAULT;
  47.         return;
  48.         }
  49.     l = (int) x;
  50.     if (l > 19 || l < 1 || l == 10)    /* no lorg (10) */
  51.         {
  52.         print_string ("LO: value out of range\n");
  53.         return;        /* no changes */
  54.         }
  55.     cp.lorg = l;    /* new label origin */
  56.     return;
  57.     }
  58.  
  59. /*--------------------------------------*/
  60.  
  61. void line_pattern (FILE * infile)
  62.     {
  63.     double x, y;
  64.     int l;
  65.  
  66.     if ( !get_val (infile, &x) )
  67.         {    /* default line type */
  68.         line_type (0, 0);
  69.         return;
  70.         }
  71.     else
  72.         {
  73.         if (x < 0)        /* line type w/pattern # */
  74.             {
  75.             print_noinstr ("Adaptive line type");
  76.             return;
  77.             }
  78.         l = (int) (MAX (0.0, MIN (6.0, x)) ) + 2;
  79.             /* translate HPGL patterns to library patterns */
  80.         if (!get_val (infile, &y))
  81.             {
  82.             line_type (l, 0);
  83.             return;
  84.             }
  85.         else    /* line type w/pattern # and repeat length */
  86.             {
  87.             line_type (l, MAX (0.0, MIN ( y, 127.9999)));
  88.             return;
  89.             }
  90.         }
  91.     return;
  92.     }
  93.  
  94. /*--------------------------------------*/
  95.  
  96. void set_csize (FILE * infile, int type)
  97.     {    /* type: 0 -> absolute, 1 -> relative */
  98.         /* set height (y) and width (x) of char (in cm) */
  99.     double x, y;
  100.  
  101.     if (type)
  102.         {        /* relative size */
  103.         cs.rcsize_x = x = 0.75;    /* width: 0.75% (p2x - p1x) */
  104.         cs.rcsize_y = y = 1.50;    /* height: 1.5% (p2y - p1y) */
  105.         }
  106.     else
  107.         {        /* absolute size */
  108.         x = 0.19;    /* default width (cm) */
  109.         y = 0.27;
  110.         }
  111.     if (get_val (infile, &x) )    /* got width value: need height */
  112.         {
  113.         if ( !get_val (infile, &y))    /* missing height */
  114.             {
  115.             if (type)
  116.                 print_string ("SR: missing height parameter\n");
  117.             else
  118.                 print_string ("SI: missing height parameter\n");
  119.             return;
  120.             }
  121.         }
  122.  
  123.     x = MAX (-128.00, (MIN (127.9999, x)));
  124.     y = MAX (-128.00, (MIN (127.9999, y)));
  125.  
  126.     calc_csize (x, y, type);    /* set char size */
  127.  
  128.     return;
  129.     }
  130.  
  131. /*--------------------------------------*/
  132.  
  133. void calc_csize (double x, double y, int type)
  134.     {
  135.     double ar;
  136.  
  137.     cs.cscale_mode = 0;    /* default to abs. char size scaling */
  138.     if (type)    /* relative char size: convert to cm */
  139.         {
  140.         cs.cscale_mode = 1;    /* turn on relative char size scaling */
  141.         cs.rcsize_x = x;
  142.         cs.rcsize_y = y;    /* save relative csizes for changes in IP */
  143.         x = x * fabs (p2x - p1x) * 0.00254 / 100.0;
  144.         y = y * fabs (p2y - p1y) * 0.00254 / 100.0;
  145.         }    /* P1, P2 are in mils.  0.00254 cm/mil */
  146.  
  147.     x = cs.csize_x = (10.0) * ((x_mirror) ? -x : x);    /* convert from cm to mm's for csize () */
  148.     y = cs.csize_y = (10.0) * ((y_mirror) ? -y : y);    /* correct for reflection/inversion of P2 - P1 */
  149.         /* cs.csize_x, cs.csize_y save char size for SL function */
  150.  
  151.     ar = x / fabs (y);            /* aspect ratio */
  152.     /* need fabs() to isolate AR from possibly negative y-size, but retain sign of x */
  153.  
  154.     if (!type) cs.csize_y = (y *= 0.725);
  155.         /* factor of 0.725 corrects default graphix lib font size to 
  156.         HPGL plotter font size for absolute font sizes (this is a patch) */
  157.  
  158.     csize (y, ar, cs.slant);    /* height (in cm), aspect ratio, slant (deg)  */
  159.     return;
  160.     }
  161.  
  162. /*--------------------------------------*/
  163.  
  164. void set_slant ( FILE *infile )
  165.     {
  166.     double ar, x;
  167.  
  168.     DB (printf ("SL\n");)
  169.     x = 0.0;
  170.     get_val (infile, &x);    /* if no value present, x is unchanged */
  171.     x = MAX (-128.00, (MIN (127.9999, x)));
  172.     cs.slant = RAD_2_DEG * atan (x);    /* sl is in degrees */
  173.     DB (printf ("SL: angle = %lf\n", cs.slant);)
  174.  
  175.     ar = cs.csize_x / fabs (cs.csize_y);    /* aspect ratio */
  176.     /* need fabs() to isolate AR from possibly negative y-size, but retain sign of x */
  177.  
  178.     csize (cs.csize_y, ar, cs.slant);    /* height (in cm), aspect ratio, slant (deg)  */
  179.     return;
  180.     }
  181.  
  182. /*--------------------------------------*/
  183.  
  184. void extra_space ( double x, double y)
  185.     {
  186.  
  187.     es_x = x;    /* save extra space for char_plot */
  188.     es_y = y;
  189.     char_xspace (100.0 * x, 100.0 * y);    /* char_xspace takes % values */
  190.     return;
  191.     }
  192.  
  193. /*--------------------------------------*/
  194.  
  195. void char_plot (FILE *infile)
  196.     {
  197.     double x, y, x_1, y_1;
  198.     double lsin, lcos, xdir, ydir;
  199.  
  200.     if (get_val (infile, &x))    /* get # spaces */
  201.         {    /* got x-value: try for y-value */
  202.         if (!get_val (infile, &y)) y = 0.0;    /* get # linefeeds (if any) */
  203.         }
  204.     else    /* got no x-value: default to 1 linefeed */
  205.         {
  206.         move (cp.x, cp.y);
  207.         labelf ("\n");
  208.         where (&cp.x, &cp.y);
  209.         return;
  210.         }
  211.  
  212.     /* move x spaces "horizontally" and y lines "vertically" */
  213.     /* directions depend on current label direction & mirroring */
  214.  
  215.     DB (printf ("CP: x = %lf, y = %lf, cp.dv = %d\n", x, y, cp.dv);)
  216.     DB (printf ("CP1: cp.x = %lf, cp.y = %lf\n", cp.x, cp.y);)
  217.  
  218.     move (cp.x, cp.y);
  219.     setgu ();        /* this looks like a kludge, but it gets */
  220.     where (&x_1, &y_1);    /* around problems of not knowing character */
  221.                 /* sizes in both plotter and user units */
  222.  
  223.     lcos = cos ( (cp.ldir + cp.dvdir) / RAD_2_DEG );
  224.     lsin = sin ( (cp.ldir + cp.dvdir) / RAD_2_DEG );    /* label directions */
  225.  
  226.     xdir = (x_mirror) ? -1.0 : 1.0;
  227.     ydir = (y_mirror) ? -1.0 : 1.0;    /* correct for P1/P2 mirroring */
  228.  
  229.     switch (cp.dv)    /* calculate x, y move from # x, y spaces */
  230.         {
  231.         case 0:    /* horizontal */
  232.             x = x * cs.csize_x * CP_XSCALE * xdir * (1.0 + es_x);
  233.             y = y * cs.csize_y * CP_YSCALE * ydir * (1.0 + es_y);
  234.             break;
  235.         case 1:    /* -90 degrees: 'x' chars of y-size, 'y' chars of x-size */
  236.             x = x * cs.csize_y * CP_YSCALE * ydir * (1.0 + es_y);
  237.             y = y * cs.csize_x * CP_XSCALE * xdir * (1.0 + es_x);
  238.             break;
  239.         case 2:    /* 180 degrees */
  240.             x = x * cs.csize_x * CP_XSCALE * xdir * (1.0 + es_x);
  241.             y = y * cs.csize_y * CP_YSCALE * ydir * (1.0 + es_y);
  242.             break;
  243.         case 3:    /* 90 degrees: 'x' chars of y-size, 'y' chars of x-size */
  244.             x = x * cs.csize_y * CP_YSCALE * ydir * (1.0 + es_y);
  245.             y = y * cs.csize_x * CP_XSCALE * xdir * (1.0 + es_x);
  246.             break;
  247.         default: break;
  248.         }
  249.  
  250.     /* now rotate char offset to label direction */
  251.     x_1 += x * lcos - y * lsin;
  252.     y_1 += y * lcos + x * lsin;
  253.  
  254.     move (x_1, y_1);    /* new position */
  255.     setuu ();
  256.     where (&cp.x, &cp.y);
  257.  
  258.     DB (printf ("CP2: cp.x = %lf, cp.y = %lf\n", cp.x, cp.y);)
  259.  
  260.     return;
  261.     }
  262.  
  263. /*--------------------------------------*/
  264.  
  265. void label_graph (FILE * infile)
  266.     {
  267.     double xpos, ypos, x_offset, y_offset;
  268.     unsigned char c2;
  269.     int i;
  270.  
  271.     DB (printf ("LB\n");)
  272.     setgu ();            /* switch to GDU's */
  273.     where ( &xpos, &ypos );        /* get current position in GDU's */
  274.  
  275.     x_offset = y_offset = 0.0;
  276.     if (cp.lorg < 10)    /* anchor label to edges of label */
  277.         {
  278.         switch (cp.lorg)    /* these offsets derived by experimentation */
  279.             {
  280.             case 1:
  281.                 y_offset = -0.386 * cs.csize_y;
  282.                 x_offset = -0.10 * cs.csize_x;
  283.                 break;
  284.             case 2:
  285.                 x_offset = -0.10 * cs.csize_x;
  286.                 break;
  287.             case 3:
  288.                 y_offset = 0.303 * cs.csize_y;
  289.                 x_offset = -0.10 * cs.csize_x;
  290.                 break;
  291.             case 4:
  292.                 y_offset = -0.386 * cs.csize_y;
  293.                 break;
  294.             case 5: break;    /* centered in (x,y) */
  295.             case 6:
  296.                 y_offset = 0.303 * cs.csize_y;
  297.                 break;
  298.             case 7:
  299.                 x_offset = 0.09 * cs.csize_x;
  300.                 y_offset = -0.386 * cs.csize_y;
  301.                 break;
  302.             case 8:
  303.                 x_offset = 0.09 * cs.csize_x;
  304.                 break;
  305.             case 9:
  306.                 y_offset = 0.303 * cs.csize_y;
  307.                 x_offset = 0.09 * cs.csize_x;
  308.                 break;
  309.             default: break;
  310.             }
  311.         move (xpos + x_offset, ypos + y_offset);    /* correct for normally offset label origins */
  312.         lorg (cp.lorg);
  313.         }
  314.     else    /* normal label origins:  offset from edges of labels */
  315.         {
  316.         lorg (cp.lorg - 10);
  317.         }
  318.     setuu ();    /* back to user units */
  319.     i = 0;
  320.     while ( 1 )
  321.         {
  322.         label_bfr[i] = c2 = getc (infile);
  323.         if (i >= LABEL_BFR - 1 || c2 == '\n')
  324.              {
  325.             label_bfr[++i] = '\0';        /* terminate label string */
  326.             labelf ("%s", label_bfr);    /* label the plot */
  327.             if (c2 == '\n')
  328.                 {
  329.                 setgu ();
  330.                 imove (-x_offset, -y_offset);    /* remove for label origin offset */
  331.                 setuu ();
  332.                 where (&cp.x, &cp.y);        /* get label position: new <cr> position for CP fn. */
  333.                 setgu ();
  334.                 imove (x_offset, y_offset);    /* restore for label origin offset */
  335.                 setuu ();
  336.                 }
  337.             i = 0;
  338.             continue;
  339.             }
  340.         if (c2 == endlabel || c2 == (char) EOF)
  341.              {
  342.             label_bfr[i] = '\0';        /* terminate label string */
  343.             labelf ("%s", label_bfr);    /* label the plot */
  344.             setgu ();
  345.             imove (-x_offset, -y_offset);    /* remove for label origin offset */
  346.             setuu ();
  347.             break;
  348.             }
  349.         label_bfr[i++] = c2;
  350.          }
  351.     DB (printf ("end: LB\n");)
  352.     plotted_on (1);        /* we drew something on this plot */
  353.     return;
  354.     }
  355.  
  356. /*--------------------------------------*/
  357.  
  358. void define_path (FILE * infile)
  359.     {
  360.     double path, line;
  361.     int l, p;
  362.  
  363.     if (!get_val (infile, &path))    /* no parameters-> defaults */
  364.         {
  365.         cp.dv = 0;    /* store label direction for CP fn. */
  366.         cp.dvdir = 0.0;    /* clear stacking direction */
  367.         cdir (0);    /* char direction along label direction */
  368.         ldir (cp.ldir);    /* horizontal label directions */
  369.         return;
  370.         }
  371.     if (path < 0.0 || path > 3.0)
  372.         return;        /* illegal values: do nothing */
  373.     p = (int) path;
  374.     if ( get_val (infile, &line))
  375.         {    /* have a linefeed type param */
  376.         print_string ("DV: linefeed parameter not implimented\n");
  377.         if (line != 0.0 || line != 1.0)
  378.             l = 0;    /* force default for illegal value */
  379.         else
  380.             l = (int) line;
  381.         }
  382.  
  383.     switch (p)
  384.         {
  385.         case 0:            /* normal directions */
  386.             cdir (0.0);
  387.             cp.dvdir = 0.0;    /* normal stacking direction */
  388.             cp.dv = 0;    /* store direction code for CP fn. */
  389.             break;
  390.         case 1:            /* down with vertical stacking */
  391.             cdir (90.0);
  392.             cp.dvdir = -90.0;    /* downward label stacking */
  393.             cp.dv = 1;    /* store label direction for CP fn. */
  394.             break;
  395.         case 2:            /* left, with reversed lettering */
  396.             cdir (180.0);
  397.             cp.dvdir = 180.0;    /* left label stacking */
  398.             cp.dv = 2;    /* store label direction for CP fn. */
  399.             break;
  400.         case 3:            /* up with vertical stacking, reversed */
  401.             cdir (-90.0);
  402.             cp.dvdir = 90.0;    /* upward label stacking */
  403.             cp.dv = 3;    /* store label direction for CP fn. */
  404.             break;
  405.         default: break;
  406.         }
  407.     ldir (cp.ldir + cp.dvdir);    /* rotate DV angle by label direction */
  408.     return;
  409.     }
  410.  
  411. /*--------------------------------------*/
  412.  
  413. void symbol_mark (unsigned char symbol)
  414.     {
  415.  
  416.     lorg (5);
  417.     labelf ("%c", symbol);
  418.     if (cp.lorg < 10)
  419.         lorg (cp.lorg);
  420.     else
  421.         lorg (cp.lorg - 10);
  422.     return;
  423.     }
  424.  
  425. /*--------------------------------------*/
  426.  
  427. void label_term (FILE * infile)
  428.     {
  429.     unsigned l;
  430.     double x;
  431.  
  432.     l = (unsigned) getc (infile);
  433.     /* test for illegal values */
  434.     if ( l < 1 || l > 127 || l == 5 || l == 27) return;
  435.     endlabel = l;
  436.     return;
  437.     }
  438.  
  439. /*--------------------------------------*/
  440.  
  441. void label_dir (FILE * infile, int type)
  442.     {    /* set relative character direction */
  443.     double rise, run;
  444.  
  445.     if ( !get_val (infile, &run))    /* get run value */
  446.          {    /* No value: ldir defaults to 0.0 */
  447.          cp.ldir = 0.0;    /* save for CP fn. */
  448.         ldir (cp.dvdir);    /* label in direction of text stacking */
  449.         return;
  450.         }
  451.     if ( !get_val (infile, &rise))    /* get rise value */
  452.         {
  453.         return;    /* no rise coordinate: error: do nothing */
  454.         }
  455.     if (!type)    /* absolute label direction */
  456.         {    /* set absolute angle, & save for CP fn. */
  457.         cp.ldir = RAD_2_DEG * atan2 (rise, run);
  458.         ldir ( cp.ldir + cp.dvdir );
  459.         return;
  460.         }
  461.  
  462.     if (rise < -128.0 || rise > 127.9999 || run < -128.0 || run > 127.9999) return;    /* fault */
  463.     rise = rise * (p2y - p1y) / 100.0;
  464.     run = run * (p2x - p1x) / 100.0;    /* relative angle determined by delta P1:P2
  465.         /* set relative angle & save for CP fn. */
  466.     cp.ldir = RAD_2_DEG * atan2 (rise, run);
  467.     ldir ( cp.ldir + cp.dvdir );
  468.  
  469.     return;
  470.     }
  471.  
  472. /*--------------------------------------*/
  473.  
  474. void begin_plot (FILE * infile)
  475.     {
  476.     double x;
  477.     unsigned l;
  478.     unsigned char c;
  479.  
  480.  
  481.     if ( plotted_on (0) )
  482.         {
  483.         twait (infile, PG_DELAY);    /* if we have a plot already up, delay screen clear */
  484.         gclear ();
  485.         }
  486.     initialize (infile);        /* initialize plotter */
  487.  
  488.     if (!get_val (infile, &x)) return;    /* no arguments */
  489.  
  490.     do        /* process arguments */
  491.         {
  492.         l = (int) x;
  493.         switch (l)
  494.             {
  495.             case 1:    /* newstring (in quotes) */
  496.                 c = getc (infile);    /* find 1st '"' char */
  497.                 while (c  && c != (unsigned char) EOF && c != '"') c = getc (infile);
  498.                 c = getc (infile);    /* dump everything through next '"' char */
  499.                 while (c  && c != (unsigned char) EOF && c != '"') c = getc (infile);
  500.                 break;
  501.             case 2:    /* number of copies: NOP */
  502.                 if (!get_val (infile, &x))    /* mus supply a value, anyway */
  503.                     {
  504.                     print_string ("BP: missing argument to number of copies\n");
  505.                     return;
  506.                     }
  507.                 break;
  508.             case 3:    /* file disposition code: NOP */
  509.                 if (!get_val (infile, &x))    /* must supply a disposition code, anyway */
  510.                     {
  511.                     print_string ("BP: missing file disposition code\n");
  512.                     return;
  513.                     }
  514.                 break;
  515.             case 4:    /* render last plot if unfinished */
  516.                 if (!get_val (infile, &x))
  517.                     {
  518.                     print_string ("BP: incomplete 'unfinished plot' rendering code\n");
  519.                     break;
  520.                     }
  521.             default:
  522.                 print_string ("BP: invalid kind parameter\n");
  523.                 return;    /* stop processing BP at invalid kind */
  524.                 break;
  525.             }
  526.         }
  527.     while (get_val (infile, &x));
  528.  
  529.     return;
  530.     }
  531.  
  532. /*--------------------------------------*/
  533.  
  534. void page_adv (FILE * infile)
  535.     {
  536.     double x;
  537.  
  538.     get_val (infile, &x);    /* get possibly one value */
  539.     setgu ();
  540.     move (0.0, 0.0);    /* move to lower left corner of hard clip */
  541.     setuu ();
  542.     twait (infile, PG_DELAY);    /* delay PG_DELAY seconds */
  543.     gclear ();
  544.     plotted_on (0);        /* new page */
  545.     return;
  546.     }
  547.  
  548. /*--------------------------------------*/
  549.