home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Graphics / Gnuplot / Source / term / hpgl.trm < prev    next >
Encoding:
Text File  |  1993-03-02  |  13.8 KB  |  684 lines

  1. /*
  2.  * $Id: hpgl.trm 3.38.2.29 1992/12/01 22:21:45 woo Exp $
  3.  */
  4.  
  5. /* GNUPLOT - hpgl.trm */
  6. /*
  7.  * Copyright (C) 1990   
  8.  *
  9.  * Permission to use, copy, and distribute this software and its
  10.  * documentation for any purpose with or without fee is hereby granted, 
  11.  * provided that the above copyright notice appear in all copies and 
  12.  * that both that copyright notice and this permission notice appear 
  13.  * in supporting documentation.
  14.  *
  15.  * Permission to modify the software is granted, but not the right to
  16.  * distribute the modified code.  Modifications are to be distributed 
  17.  * as patches to released version.
  18.  *  
  19.  * This software  is provided "as is" without express or implied warranty.
  20.  * 
  21.  * This file is included by ../term.c.
  22.  *
  23.  * This terminal driver supports:
  24.  *  hpgl, hp7580b, HP Laserjet III
  25.  *
  26.  * AUTHORS
  27.  *  Colin Kelley, Thomas Williams, Russell Lang
  28.  * 
  29.  * send your comments or suggestions to (pixar!info-gnuplot@sun.com).
  30.  * 
  31.  */
  32.  
  33. /*
  34.  *
  35.  * MODIFIED for expanded HPGL/2 and PCL utilites
  36.  *  Tom Swiler (tom@silica.mse.ufl.edu)
  37.  * 
  38.  */
  39.  
  40. /*
  41.  * The maximum plot size, in plotter units:
  42.  */
  43.  
  44. #define HPGL_PUPI    1016    /* Plotter units per inch */
  45.   
  46. #define HPGL_XMAX_A    10000
  47. #define HPGL_YMAX_A    7500
  48.   
  49. #define HPGL_XMAX_B    15200
  50. #define HPGL_YMAX_B    10000
  51.  
  52. #define HPGL_XMAX    HPGL_XMAX_A
  53. #define HPGL_YMAX    HPGL_YMAX_A
  54.   
  55. #define PCL_XMAX    HPGL_XMAX_A
  56. #define PCL_YMAX    HPGL_YMAX_A
  57.  
  58. /*
  59.  * Tic sizes
  60.  */
  61.  
  62. #define HPGL_VTIC    (HPGL_YMAX/70)
  63. #define HPGL_HTIC    (HPGL_YMAX/70)
  64.  
  65. #define PCL_VTIC    (PCL_YMAX/70)
  66. #define PCL_HTIC    (PCL_YMAX/70)
  67.  
  68. /*
  69.  * Font size for HPGL
  70.  */
  71.  
  72. #define HPGL_VCHAR    (HPGL_YMAX/100*32/10) /* 3.2% */
  73. #define HPGL_HCHAR    (HPGL_XMAX/100*12/10) /* 1.2% */
  74.  
  75. /*
  76.  * Font size for HPGL/2
  77.  */
  78.  
  79. #define HPGL2_DEF_POINT    14    /* Height of font */
  80.  
  81. #define HPGL2_DEF_PITCH    (3 * 72 / (HPGL2_DEF_POINT * 2))
  82. #define HPGL2_VCHAR    ((int) HPGL_PUPI * HPGL2_DEF_POINT / 72)
  83. #define HPGL2_HCHAR    (HPGL2_VCHAR * 2 / 3)
  84.  
  85. /*
  86.  * Control constants
  87.  */
  88.  
  89. #define DOWN        0    /* Pen is down */
  90. #define UP         1    /* Pen is up */
  91. #define UNKNOWN        -10    /* Unknown status for lots of things */
  92.  
  93. /*
  94.  * For Polyline Encoded, either use base 64 or base 32.
  95.  * Save space with base 64, but get 8-bit characters.
  96.  */
  97.  
  98. #define HPGL2_BASE64 TRUE
  99.  
  100. #if HPGL2_BASE64
  101. #define HPGL2_BITS 6
  102. #define HPGL2_LOW_OFFS 63
  103. #define HPGL2_HIGH_OFFS 191
  104. #define HPGL2_MASK 63
  105. #else
  106. #define HPGL2_BITS 5
  107. #define HPGL2_LOW_OFFS 63
  108. #define HPGL2_HIGH_OFFS 95
  109. #define HPGL2_MASK 31
  110. #endif
  111.  
  112. /*
  113.  * Data structures for options
  114.  */
  115.  
  116. struct HPGL2_font_str {
  117.     char           *compare,
  118.                    *name;
  119.     int             symbol_set,
  120.                     spacing;
  121.     double          pitch,
  122.                     height;
  123.     int             posture,
  124.                     stroke_weight,
  125.                     typeface;
  126. };
  127.  
  128. struct PCL_mode_str {
  129.     char           *compare,
  130.                    *name,
  131.                    *command;
  132.     int             xmax,
  133.                     ymax;
  134. };
  135.  
  136. /*
  137.  * The default font goes first.  Although it is the ugliest,  the
  138.  * stick font is probably supported by the most devices, so it
  139.  * becomes the default.
  140.  */
  141.  
  142. static struct HPGL2_font_str HPGL2_font_table[] = {
  143.         {"u$nivers", "univers", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 4148},
  144.          {"s$tick", "stick", 277, 0, HPGL2_DEF_PITCH, 0.0, 0, 0, 48},
  145.        {"c$g_times", "cg_times", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 4101}
  146. };
  147.  
  148. #define HPGL2_FONTS (sizeof(HPGL2_font_table) / sizeof (struct HPGL2_font_str))
  149. static struct HPGL2_font_str *HPGL2_font = &HPGL2_font_table[0];
  150.  
  151. /*
  152.  * The default mode goes first.  Landscape style plots are probably the
  153.  * most compatable with other HPGL devices.
  154.  */
  155.  
  156. static struct PCL_mode_str PCL_mode_table[] = {
  157.           {"l$andscape", "landscape", "\033&l1O", PCL_XMAX, PCL_YMAX},
  158.          {"p$ortrait", "portrait", "\033&l0O", PCL_YMAX, PCL_XMAX}
  159. };
  160.  
  161. #define PCL_MODES (sizeof(PCL_mode_table) / sizeof (struct PCL_mode_str))
  162. static struct PCL_mode_str *PCL_mode = &PCL_mode_table[0];
  163.  
  164. /*
  165.  * Various line types and widths to distinguish data sets
  166.  */
  167.  
  168. static char    *HPGL2_lt[] = {"", "4,2", "5,2", "6,2", "7,2", "8,2"},
  169.                *HPGL2_pw[] = {".15", ".12", ".08"};
  170.  
  171. #define HPGL2_LINETYPES (sizeof(HPGL2_lt) / sizeof(char *))
  172. #define HPGL2_PENWIDTHS (sizeof(HPGL2_pw) / sizeof(char *))
  173.  
  174. /*
  175.  * Static variables to keep track of where we are, etc.
  176.  */
  177.  
  178. static int      HPGL_ang = 0,
  179.                 HPGL_x = UNKNOWN,
  180.                 HPGL_y = UNKNOWN,
  181.                 HPGL_penstate = UNKNOWN,
  182.                 HPGL_pentype = UNKNOWN,
  183.                 HPGL2_in_pe,
  184.                 HPGL2_lost;
  185.  
  186. /*
  187.  * The subroutines, grouped by function for different versions.
  188.  */
  189.  
  190. HPGL2_options ()
  191. {
  192.     extern double real();
  193.     struct termentry *t = &term_tbl[term];
  194.     int             i;
  195.     double          point_size;
  196.     char            string[MAX_ID_LEN];
  197.     char       tmp_options[MAX_ID_LEN];
  198.     if (!END_OF_COMMAND) {
  199.     for (i = 0; i < HPGL2_FONTS &&
  200.          !almost_equals (c_token, HPGL2_font_table[i].compare); i++);
  201.     if (i < HPGL2_FONTS) {
  202.         HPGL2_font = &HPGL2_font_table[i];
  203.     } else
  204.         int_error ("expecting font: stick, cg_times, or univers", c_token);
  205.     c_token++;
  206.     if (!END_OF_COMMAND) {
  207.         if ((point_size = real(&token[c_token].l_val)) > 0.0) {
  208.         t->v_char = (int) HPGL_PUPI *point_size / 72;
  209.         t->h_char = t->v_char * 2 / 3;
  210.         if (HPGL2_font->spacing)
  211.             HPGL2_font->height = point_size;
  212.         else
  213.             HPGL2_font->pitch = 72 * 3 / (point_size * 2);
  214.         } else
  215.         int_error ("expecting font point size: real number",c_token);
  216.         c_token++;
  217.     }
  218.     }
  219.     sprintf (tmp_options, " %s", HPGL2_font->name);
  220.     strcat(term_options,tmp_options);
  221.     if (HPGL2_font->spacing){
  222.     sprintf (tmp_options, " %lf",
  223.           HPGL2_font->height);
  224.     strcat(term_options,tmp_options);
  225.     }else{
  226.     sprintf (tmp_options, " %lf",
  227.           HPGL2_font->pitch);
  228.         strcat(term_options,tmp_options);
  229.     }
  230. }
  231.  
  232. PCL_options ()
  233. {
  234.     int             i;
  235.     if (!END_OF_COMMAND) {
  236.     for (i = 0; i < PCL_MODES &&
  237.          !almost_equals (c_token, PCL_mode_table[i].compare); i++);
  238.     if (i < PCL_MODES)
  239.         PCL_mode = &PCL_mode_table[i];
  240.     else
  241.         int_error ("expecting mode: portrait or landscape", c_token);
  242.     c_token++;
  243.     }
  244.     sprintf (term_options, " %s", PCL_mode->name);
  245.     HPGL2_options ();
  246. }
  247.  
  248. HPGL_init ()
  249. {
  250. }
  251.  
  252. HPGL2_init ()
  253. {
  254. }
  255.  
  256. PCL_init ()
  257. {
  258.     struct termentry *t = &term_tbl[term];
  259. /*
  260.  * Reset printer, set to one copy, orientation of user's choice.
  261.  * Make the change to the new orientation all at once.
  262.  */
  263.     fprintf (outfile, "\033E\033&l1X%s", PCL_mode->command);
  264.     t->xmax = PCL_mode->xmax;
  265.     t->ymax = PCL_mode->ymax;
  266. }
  267.  
  268. HPGL_graphics()
  269. {
  270.     fputs("\033.Y\n\033.I81;;17:\033.N;19:\033.M500:\n",outfile);
  271. /*           1
  272.     1. enable eavesdropping
  273. */
  274.     fprintf(outfile,
  275.     "IN;\nSC0,%d,0,%d;\nSR%f,%f;\n",
  276.         HPGL_XMAX,HPGL_YMAX,
  277.         ((double)(HPGL_HCHAR)*200/3/HPGL_XMAX),
  278.         ((double)(HPGL_VCHAR)*100/2/HPGL_YMAX) );
  279. /*     1    2             3 
  280.     1. reset to power-up defaults
  281.     2. set SCaling
  282.     3. set character size
  283. */
  284.     HPGL_ang = 0;
  285. }
  286.  
  287. HPGL2_graphics ()
  288. {
  289. /*
  290.  * IN - Initialize
  291.  * SP - Select pen
  292.  * SD - Set default font
  293.  */
  294.     fprintf (outfile, "INSP1SD1,%d,2,%d,",
  295.          HPGL2_font->symbol_set, HPGL2_font->spacing);
  296.     if (HPGL2_font->spacing)
  297.     fprintf (outfile, "4,%lf,", HPGL2_font->height);
  298.     else
  299.     fprintf (outfile, "3,%lf,", HPGL2_font->pitch);
  300.     fprintf (outfile, "5,%d,6,%d,7,%d", HPGL2_font->posture,
  301.          HPGL2_font->stroke_weight, HPGL2_font->typeface);
  302. /*
  303.  * Control variables
  304.  */
  305.     HPGL_ang = 0;        /* Horizontal */
  306.     HPGL2_in_pe = FALSE;    /* Not in PE command */
  307.     HPGL2_lost = TRUE;        /* Pen position is unknown */
  308.     HPGL_penstate = UP;        /* Pen is up */
  309. }
  310.  
  311. PCL_graphics ()
  312. {
  313. /*
  314.  * Enter HPGL/2 graphics mode
  315.  */
  316.     fputs ("\033%0B", outfile);
  317.     HPGL2_graphics ();
  318. }
  319.  
  320. HPGL_text ()
  321. {
  322.     fputs ("PUSP0;\033.Z\0", outfile);
  323. /*           1 2   3
  324.     1. pen up
  325.     2. park pen
  326.     3. disable eavesdropping
  327. */
  328.     HPGL_penstate = UP;
  329. }
  330.  
  331. HPGL2_text ()
  332. {
  333. /*
  334.  * If in Polyline Encoded command, leave Polyline Encoded command
  335.  */
  336.     if (HPGL2_in_pe) {
  337.     fputs (";", outfile);
  338.     HPGL2_in_pe = 0;
  339.     }
  340. /*
  341.  * Pen up, park pen
  342.  */
  343.     fputs ("PUSP0;", outfile);
  344. }
  345.  
  346. PCL_text ()
  347. {
  348.     if (HPGL2_in_pe) {
  349.     fputs (";", outfile);
  350.     HPGL2_in_pe = 0;
  351.     }
  352. /*
  353.  * Go into PCL mode and eject the page
  354.  */
  355.     fputs ("\033%1A\033&l0H\0", outfile);
  356. }
  357.  
  358. HPGL_linetype (linetype)
  359.     int             linetype;
  360. {
  361. /* allow for 6 pens */
  362.     linetype = (linetype + 2) % 6 + 1;
  363. /* only select pen if necessary */
  364.     if (HPGL_pentype != linetype) {
  365.     fprintf (outfile, "PU;\nSP%d;\n", linetype);
  366.     HPGL_pentype = linetype;
  367.     HPGL_penstate = UP;
  368.     }
  369. }
  370.  
  371. HP75_linetype (linetype)
  372.     int             linetype;
  373. {
  374. /* allow for 4 pens */
  375.     linetype = (linetype + 2) % 4 + 1;
  376. /* only select pen if necessary */
  377.     if (HPGL_pentype != linetype) {
  378.     fprintf (outfile, "PU;\nSP%d;\n", linetype);
  379.     HPGL_pentype = linetype;
  380.     HPGL_penstate = UP;
  381.     }
  382. }
  383.  
  384. HPGL2_linetype (linetype)
  385.     int             linetype;
  386. {
  387. /*
  388.  * If in Polyline Encoded command, leave Polyline Encoded command
  389.  */
  390.     if (HPGL2_in_pe) {
  391.     fputs (";", outfile);
  392.     HPGL2_in_pe = 0;
  393.     }
  394. /*
  395.  * Allow for lots of linetypes
  396.  */
  397.     if (linetype >= 0)
  398.     linetype = linetype % (HPGL2_LINETYPES * HPGL2_PENWIDTHS);
  399.     if (linetype != HPGL_pentype) {
  400.     if (linetype >= 0) {
  401.         fprintf (outfile, "PW%sLT%s",
  402.              HPGL2_pw[linetype / HPGL2_LINETYPES],
  403.              HPGL2_lt[linetype % HPGL2_LINETYPES]);
  404.     } else if (linetype == -2)
  405. /*
  406.  * Borders and tics
  407.  */
  408.         fprintf (outfile, "PW.2LT");
  409.     else if (linetype == -1)
  410. /*
  411.  * Axes and grids
  412.  */
  413.         fprintf (outfile, "PW.1LT1,.25");
  414.     HPGL_pentype = linetype;
  415.     }
  416. }
  417.  
  418. HPGL_put_text (x, y, str)
  419.     int             x,
  420.                     y;
  421.     char           *str;
  422. {
  423.     if (HPGL_ang == 1)
  424.     HPGL_move (x + HPGL_VCHAR / 4, y);
  425.     else
  426.     HPGL_move (x, y - HPGL_VCHAR / 4);
  427.     fprintf (outfile, "LB%s\003\n", str);
  428. }
  429.  
  430. HPGL2_put_text (x, y, str)
  431.     int             x,
  432.                     y;
  433.     char           *str;
  434. {
  435.     struct termentry *t = &term_tbl[term];
  436. /*
  437.  * Position the pen
  438.  */
  439.     if (HPGL_ang == 1)
  440.     HPGL2_move (x + t->v_char / 4, y);
  441.     else
  442.     HPGL2_move (x, y - t->v_char / 4);
  443. /*
  444.  * If in Polyline Encoded command, leave Polyline Encoded command
  445.  */
  446.     if (HPGL2_in_pe) {
  447.     fputs (";", outfile);
  448.     HPGL2_in_pe = 0;
  449.     }
  450. /*
  451.  * Print the text string
  452.  */
  453.     fprintf (outfile, "LB%s\003", str);
  454.     HPGL2_lost = 1;
  455. }
  456. /*
  457.  * Some early HPGL plotters (e.g. HP7220C) require the
  458.  * Pen Up/Down and Pen (move) Absolute commands to be separate.
  459.  */
  460.  
  461. HPGL_move (x, y)
  462.     int             x,
  463.                     y;
  464. {
  465.     if (HPGL_x != x || HPGL_y != y) {        /* only move if necessary */
  466.     fprintf (outfile, "PU;PA%d,%d;\n", x, y);
  467.     HPGL_penstate = UP;
  468.     HPGL_x = x;
  469.     HPGL_y = y;
  470.     }
  471. }
  472.  
  473. HPGL_vector (x, y)
  474.     int             x,
  475.                     y;
  476. {
  477.     if (HPGL_penstate != DOWN) {
  478.     fprintf (outfile, "PD;PA%d,%d;\n", x, y);
  479.     HPGL_penstate = DOWN;
  480.     } else
  481.     fprintf (outfile, "PA%d,%d;\n", x, y);
  482.     HPGL_x = x;
  483.     HPGL_y = y;
  484. }
  485.  
  486. HPGL2_move (x, y)
  487.     int             x,
  488.                     y;
  489. {
  490.     register int    dx,
  491.                     dy,
  492.                     c;
  493.     if (HPGL2_in_pe) {
  494.     dx = x - HPGL_x;
  495.     dy = y - HPGL_y;
  496.     fputs ("<", outfile);
  497.     } else {
  498. #if HPGL2_BASE64
  499.     fputs ("PE<", outfile);
  500. #else
  501.     fputs ("PE7<", outfile);
  502. #endif
  503.     if (HPGL2_lost) {
  504.         dx = x;
  505.         dy = y;
  506.         HPGL2_lost = 0;
  507.         fputs ("=", outfile);
  508.     } else {
  509.         dx = x - HPGL_x;
  510.         dy = y - HPGL_y;
  511.     }
  512.     HPGL2_in_pe = 1;
  513.     }
  514. #if HPGL2_EXPLICIT_PD
  515.     if (HPGL_penstate == DOWN)
  516.     HPGL_penstate = UP;
  517. #endif
  518.     HPGL2_encode (dx);
  519.     HPGL2_encode (dy);
  520.     HPGL_x = x;
  521.     HPGL_y = y;
  522. }
  523.  
  524. HPGL2_vector (x, y)
  525.     int             x,
  526.                     y;
  527. {
  528.     register int    dx,
  529.                     dy,
  530.                     c;
  531.     if (HPGL2_in_pe) {
  532.     dx = x - HPGL_x;
  533.     dy = y - HPGL_y;
  534.     } else {
  535. #if HPGL2_BASE64
  536.     fputs ("PE", outfile);
  537. #else
  538.     fputs ("PE7", outfile);
  539. #endif
  540.     if (HPGL2_lost) {
  541.         dx = x;
  542.         dy = y;
  543.         HPGL2_lost = 0;
  544.         fputs ("=", outfile);
  545.     } else {
  546.         dx = x - HPGL_x;
  547.         dy = y - HPGL_y;
  548.     }
  549.     HPGL2_in_pe = 1;
  550.     }
  551. #if HPGL2_EXPLICIT_PD
  552. /*
  553.  * Put the pen down in the current position,
  554.  * relative vector of 0,0.
  555.  */
  556.     if (HPGL_penstate == UP) {
  557.     fputc ((char) HPGL2_HIGH_OFFS, outfile);
  558.     fputc ((char) HPGL2_HIGH_OFFS, outfile);
  559.     HPGL_penstate = DOWN;
  560.     }
  561. #endif
  562.     HPGL2_encode (dx);
  563.     HPGL2_encode (dy);
  564.     HPGL_x = x;
  565.     HPGL_y = y;
  566. }
  567.  
  568. /*
  569.  * Routine to encode position in base 32 or base 64 characters
  570.  */
  571.  
  572. HPGL2_encode (d)
  573.     register int    d;
  574. {
  575.     register int    c;
  576.     if ((d <<= 1) < 0)
  577.     d = 1 - d;
  578.     do {
  579.     c = d & HPGL2_MASK;
  580.     d >>= HPGL2_BITS;
  581.     if (d > 0)
  582.         fputc ((char) (c + HPGL2_LOW_OFFS), outfile);
  583.     else
  584.         fputc ((char) (c + HPGL2_HIGH_OFFS), outfile);
  585.     } while (d > 0);
  586. }
  587.  
  588. int
  589. HPGL_text_angle (ang)
  590.     int             ang;
  591. {
  592.     HPGL_ang = ang;
  593.     if (ang == 1)
  594. /*
  595.  *  Vertical
  596.  */
  597.     fprintf (outfile, "DI0,1;\n");
  598.     else
  599. /*
  600.  * Horizontal
  601.  */
  602.     fprintf (outfile, "DI1,0;\n");
  603.     return TRUE;
  604. }
  605.  
  606. int
  607. HPGL2_text_angle (ang)
  608.     int             ang;
  609. {
  610. /*
  611.  * If in Polyline Encoded command, leave Polyline Encoded command
  612.  */
  613.     if (HPGL2_in_pe) {
  614.     fputs (";", outfile);
  615.     HPGL2_in_pe = 0;
  616.     }
  617.     if (ang == 1)
  618. /*
  619.  *  Vertical
  620.  */
  621.     fprintf (outfile, "DI0,1");
  622.     else
  623. /*
  624.  * Horizontal
  625.  */
  626.     fprintf (outfile, "DI1,0");
  627.     HPGL_ang = ang;
  628.     return TRUE;
  629. }
  630.  
  631. HPGL_reset ()
  632. {
  633. /*
  634.  * I am not sure that "PG" is a command in HPGL.
  635.  */
  636.     fputs ("PG;", outfile);
  637. }
  638.  
  639. HPGL2_reset ()
  640. {
  641. /*
  642.  * Park the pen
  643.  * Advance a page
  644.  * End with ";"
  645.  */
  646.     fputs ("SP0PG;", outfile);
  647. }
  648.  
  649. PCL_reset ()
  650. {
  651. /*
  652.  * Return to PCL mode
  653.  * Printer reset (conditional eject)
  654.  */
  655.     fputs ("\033%0A\033E\n", outfile);
  656. }
  657.  
  658. HPGL2_justify_text (just)
  659.     int             just;
  660. {
  661. /*
  662.  * If in Polyline Encoded command, leave Polyline Encoded command
  663.  */
  664.     if (HPGL2_in_pe) {
  665.     fputs (";", outfile);
  666.     HPGL2_in_pe = 0;
  667.     }
  668.     switch (just) {
  669.     case LEFT:
  670.     fputs ("LO1", outfile);
  671.     break;
  672.     case CENTRE:
  673.     fputs ("LO4", outfile);
  674.     break;
  675.     case RIGHT:
  676.     fputs ("LO7", outfile);
  677.     break;
  678.     default:
  679.     return 0;
  680.     }
  681.     return 1;
  682. }
  683.  
  684.