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