home *** CD-ROM | disk | FTP | other *** search
/ CICA 1995 May / cica_0595_4.zip / cica_0595_4 / UTIL / GPT34SRC / TERM / HPGL.TRM < prev    next >
Text File  |  1993-05-11  |  15KB  |  683 lines

  1. /*
  2.  * $Id: hpgl.trm%v 3.38.2.125 1993/05/05 00:13:05 woo Exp woo $
  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 (info-gnuplot@dartmouth.edu).
  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 GPFAR 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 GPFAR 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       tmp_options[MAX_ID_LEN];
  197.     if (!END_OF_COMMAND) {
  198.     for (i = 0; i < HPGL2_FONTS &&
  199.          !almost_equals (c_token, HPGL2_font_table[i].compare); i++);
  200.     if (i < HPGL2_FONTS) {
  201.         HPGL2_font = &HPGL2_font_table[i];
  202.     } else
  203.         int_error ("expecting font: stick, cg_times, or univers", c_token);
  204.     c_token++;
  205.     if (!END_OF_COMMAND) {
  206.         if ((point_size = real(&token[c_token].l_val)) > 0.0) {
  207.         t->v_char = (int) HPGL_PUPI *point_size / 72;
  208.         t->h_char = t->v_char * 2 / 3;
  209.         if (HPGL2_font->spacing)
  210.             HPGL2_font->height = point_size;
  211.         else
  212.             HPGL2_font->pitch = 72 * 3 / (point_size * 2);
  213.         } else
  214.         int_error ("expecting font point size: real number",c_token);
  215.         c_token++;
  216.     }
  217.     }
  218.     sprintf (tmp_options, " %s", HPGL2_font->name);
  219.     strcat(term_options,tmp_options);
  220.     if (HPGL2_font->spacing){
  221.     sprintf (tmp_options, " %lf",
  222.           HPGL2_font->height);
  223.     strcat(term_options,tmp_options);
  224.     }else{
  225.     sprintf (tmp_options, " %lf",
  226.           HPGL2_font->pitch);
  227.         strcat(term_options,tmp_options);
  228.     }
  229. }
  230.  
  231. PCL_options ()
  232. {
  233.     int             i;
  234.     if (!END_OF_COMMAND) {
  235.     for (i = 0; i < PCL_MODES &&
  236.          !almost_equals (c_token, PCL_mode_table[i].compare); i++);
  237.     if (i < PCL_MODES)
  238.         PCL_mode = &PCL_mode_table[i];
  239.     else
  240.         int_error ("expecting mode: portrait or landscape", c_token);
  241.     c_token++;
  242.     }
  243.     sprintf (term_options, " %s", PCL_mode->name);
  244.     HPGL2_options ();
  245. }
  246.  
  247. HPGL_init ()
  248. {
  249. }
  250.  
  251. HPGL2_init ()
  252. {
  253. }
  254.  
  255. PCL_init ()
  256. {
  257.     struct termentry *t = &term_tbl[term];
  258. /*
  259.  * Reset printer, set to one copy, orientation of user's choice.
  260.  * Make the change to the new orientation all at once.
  261.  */
  262.     fprintf (outfile, "\033E\033&l1X%s\n", PCL_mode->command);
  263.     t->xmax = PCL_mode->xmax;
  264.     t->ymax = PCL_mode->ymax;
  265. }
  266.  
  267. HPGL_graphics()
  268. {
  269.     fputs("\033.Y\n\033.I81;;17:\033.N;19:\033.M500:\n",outfile);
  270. /*           1
  271.     1. enable eavesdropping
  272. */
  273.     fprintf(outfile,
  274.     "IN;\nSC0,%d,0,%d;\nSR%f,%f;\n",
  275.         HPGL_XMAX,HPGL_YMAX,
  276.         ((double)(HPGL_HCHAR)*200/3/HPGL_XMAX),
  277.         ((double)(HPGL_VCHAR)*100/2/HPGL_YMAX) );
  278. /*     1    2             3 
  279.     1. reset to power-up defaults
  280.     2. set SCaling
  281.     3. set character size
  282. */
  283.     HPGL_ang = 0;
  284. }
  285.  
  286. HPGL2_graphics ()
  287. {
  288. /*
  289.  * IN - Initialize
  290.  * SP - Select pen
  291.  * SD - Set default font
  292.  */
  293.     fprintf (outfile, "INSP1SD1,%d,2,%d,",
  294.          HPGL2_font->symbol_set, HPGL2_font->spacing);
  295.     if (HPGL2_font->spacing)
  296.     fprintf (outfile, "4,%lf,", HPGL2_font->height);
  297.     else
  298.     fprintf (outfile, "3,%lf,", HPGL2_font->pitch);
  299.     fprintf (outfile, "5,%d,6,%d,7,%d\n", HPGL2_font->posture,
  300.          HPGL2_font->stroke_weight, HPGL2_font->typeface);
  301. /*
  302.  * Control variables
  303.  */
  304.     HPGL_ang = 0;        /* Horizontal */
  305.     HPGL2_in_pe = FALSE;    /* Not in PE command */
  306.     HPGL2_lost = TRUE;        /* Pen position is unknown */
  307.     HPGL_penstate = UP;        /* Pen is up */
  308. }
  309.  
  310. PCL_graphics ()
  311. {
  312. /*
  313.  * Enter HPGL/2 graphics mode
  314.  */
  315.     fputs ("\033%0B", outfile);
  316.     HPGL2_graphics ();
  317. }
  318.  
  319. HPGL_text ()
  320. {
  321.     fputs ("PUSP0;\033.Z\n\0", outfile);
  322. /*           1 2   3
  323.     1. pen up
  324.     2. park pen
  325.     3. disable eavesdropping
  326. */
  327.     HPGL_penstate = UP;
  328. }
  329.  
  330. HPGL2_text ()
  331. {
  332. /*
  333.  * If in Polyline Encoded command, leave Polyline Encoded command
  334.  */
  335.     if (HPGL2_in_pe) {
  336.     fputs (";\n", outfile);
  337.     HPGL2_in_pe = 0;
  338.     }
  339. /*
  340.  * Pen up, park pen
  341.  */
  342.     fputs ("PUSP0;", outfile);
  343. }
  344.  
  345. PCL_text ()
  346. {
  347.     if (HPGL2_in_pe) {
  348.     fputs (";\n", outfile);
  349.     HPGL2_in_pe = 0;
  350.     }
  351. /*
  352.  * Go into PCL mode and eject the page
  353.  */
  354.     fputs ("\033%1A\033&l0H\n\0", outfile);
  355. }
  356.  
  357. HPGL_linetype (linetype)
  358.     int             linetype;
  359. {
  360. /* allow for 6 pens */
  361.     linetype = (linetype + 2) % 6 + 1;
  362. /* only select pen if necessary */
  363.     if (HPGL_pentype != linetype) {
  364.     fprintf (outfile, "PU;\nSP%d;\n", linetype);
  365.     HPGL_pentype = linetype;
  366.     HPGL_penstate = UP;
  367.     }
  368. }
  369.  
  370. HP75_linetype (linetype)
  371.     int             linetype;
  372. {
  373. /* allow for 4 pens */
  374.     linetype = (linetype + 2) % 4 + 1;
  375. /* only select pen if necessary */
  376.     if (HPGL_pentype != linetype) {
  377.     fprintf (outfile, "PU;\nSP%d;\n", linetype);
  378.     HPGL_pentype = linetype;
  379.     HPGL_penstate = UP;
  380.     }
  381. }
  382.  
  383. HPGL2_linetype (linetype)
  384.     int             linetype;
  385. {
  386. /*
  387.  * If in Polyline Encoded command, leave Polyline Encoded command
  388.  */
  389.     if (HPGL2_in_pe) {
  390.     fputs (";\n", outfile);
  391.     HPGL2_in_pe = 0;
  392.     }
  393. /*
  394.  * Allow for lots of linetypes
  395.  */
  396.     if (linetype >= 0)
  397.     linetype = linetype % (HPGL2_LINETYPES * HPGL2_PENWIDTHS);
  398.     if (linetype != HPGL_pentype) {
  399.     if (linetype >= 0) {
  400.         fprintf (outfile, "PW%sLT%s",
  401.              HPGL2_pw[linetype / HPGL2_LINETYPES],
  402.              HPGL2_lt[linetype % HPGL2_LINETYPES]);
  403.     } else if (linetype == -2)
  404. /*
  405.  * Borders and tics
  406.  */
  407.         fprintf (outfile, "PW.2LT");
  408.     else if (linetype == -1)
  409. /*
  410.  * Axes and grids
  411.  */
  412.         fprintf (outfile, "PW.1LT1,.25");
  413.     HPGL_pentype = linetype;
  414.     }
  415. }
  416.  
  417. HPGL_put_text (x, y, str)
  418.     int             x,
  419.                     y;
  420.     char           *str;
  421. {
  422.     if (HPGL_ang == 1)
  423.     HPGL_move (x + HPGL_VCHAR / 4, y);
  424.     else
  425.     HPGL_move (x, y - HPGL_VCHAR / 4);
  426.     fprintf (outfile, "LB%s\003\n", str);
  427. }
  428.  
  429. HPGL2_put_text (x, y, str)
  430.     int             x,
  431.                     y;
  432.     char           *str;
  433. {
  434.     struct termentry *t = &term_tbl[term];
  435. /*
  436.  * Position the pen
  437.  */
  438.     if (HPGL_ang == 1)
  439.     HPGL2_move (x + t->v_char / 4, y);
  440.     else
  441.     HPGL2_move (x, y - t->v_char / 4);
  442. /*
  443.  * If in Polyline Encoded command, leave Polyline Encoded command
  444.  */
  445.     if (HPGL2_in_pe) {
  446.     fputs (";\n", outfile);
  447.     HPGL2_in_pe = 0;
  448.     }
  449. /*
  450.  * Print the text string
  451.  */
  452.     fprintf (outfile, "LB%s\003\n", str);
  453.     HPGL2_lost = 1;
  454. }
  455. /*
  456.  * Some early HPGL plotters (e.g. HP7220C) require the
  457.  * Pen Up/Down and Pen (move) Absolute commands to be separate.
  458.  */
  459.  
  460. HPGL_move (x, y)
  461.     int             x,
  462.                     y;
  463. {
  464.     if (HPGL_x != x || HPGL_y != y) {        /* only move if necessary */
  465.     fprintf (outfile, "PU;PA%d,%d;\n", x, y);
  466.     HPGL_penstate = UP;
  467.     HPGL_x = x;
  468.     HPGL_y = y;
  469.     }
  470. }
  471.  
  472. HPGL_vector (x, y)
  473.     int             x,
  474.                     y;
  475. {
  476.     if (HPGL_penstate != DOWN) {
  477.     fprintf (outfile, "PD;PA%d,%d;\n", x, y);
  478.     HPGL_penstate = DOWN;
  479.     } else
  480.     fprintf (outfile, "PA%d,%d;\n", x, y);
  481.     HPGL_x = x;
  482.     HPGL_y = y;
  483. }
  484.  
  485. HPGL2_move (x, y)
  486.     int             x,
  487.                     y;
  488. {
  489.     register int    dx,
  490.                     dy;
  491.     if (HPGL2_in_pe) {
  492.     dx = x - HPGL_x;
  493.     dy = y - HPGL_y;
  494.     fputs ("<", outfile);
  495.     } else {
  496. #if HPGL2_BASE64
  497.     fputs ("PE<", outfile);
  498. #else
  499.     fputs ("PE7<", outfile);
  500. #endif
  501.     if (HPGL2_lost) {
  502.         dx = x;
  503.         dy = y;
  504.         HPGL2_lost = 0;
  505.         fputs ("=", outfile);
  506.     } else {
  507.         dx = x - HPGL_x;
  508.         dy = y - HPGL_y;
  509.     }
  510.     HPGL2_in_pe = 1;
  511.     }
  512. #if HPGL2_EXPLICIT_PD
  513.     if (HPGL_penstate == DOWN)
  514.     HPGL_penstate = UP;
  515. #endif
  516.     HPGL2_encode (dx);
  517.     HPGL2_encode (dy);
  518.     fputs("\n",outfile);
  519.     HPGL_x = x;
  520.     HPGL_y = y;
  521. }
  522.  
  523. HPGL2_vector (x, y)
  524.     int             x,
  525.                     y;
  526. {
  527.     register int    dx,
  528.                     dy;
  529.     if (HPGL2_in_pe) {
  530.     dx = x - HPGL_x;
  531.     dy = y - HPGL_y;
  532.     } else {
  533. #if HPGL2_BASE64
  534.     fputs ("PE", outfile);
  535. #else
  536.     fputs ("PE7", outfile);
  537. #endif
  538.     if (HPGL2_lost) {
  539.         dx = x;
  540.         dy = y;
  541.         HPGL2_lost = 0;
  542.         fputs ("=", outfile);
  543.     } else {
  544.         dx = x - HPGL_x;
  545.         dy = y - HPGL_y;
  546.     }
  547.     HPGL2_in_pe = 1;
  548.     }
  549. #if HPGL2_EXPLICIT_PD
  550. /*
  551.  * Put the pen down in the current position,
  552.  * relative vector of 0,0.
  553.  */
  554.     if (HPGL_penstate == UP) {
  555.     fputc ((char) HPGL2_HIGH_OFFS, outfile);
  556.     fputc ((char) HPGL2_HIGH_OFFS, outfile);
  557.     HPGL_penstate = DOWN;
  558.     }
  559. #endif
  560.     HPGL2_encode (dx);
  561.     HPGL2_encode (dy);
  562.     fputs("\n",outfile);
  563.     HPGL_x = x;
  564.     HPGL_y = y;
  565. }
  566.  
  567. /*
  568.  * Routine to encode position in base 32 or base 64 characters
  569.  */
  570.  
  571. HPGL2_encode (d)
  572.     register int    d;
  573. {
  574.     register int    c;
  575.     if ((d <<= 1) < 0)
  576.     d = 1 - d;
  577.     do {
  578.     c = d & HPGL2_MASK;
  579.     d >>= HPGL2_BITS;
  580.     if (d > 0)
  581.         fputc ((char) (c + HPGL2_LOW_OFFS), outfile);
  582.     else
  583.         fputc ((char) (c + HPGL2_HIGH_OFFS), outfile);
  584.     } while (d > 0);
  585. }
  586.  
  587. int
  588. HPGL_text_angle (ang)
  589.     int             ang;
  590. {
  591.     HPGL_ang = ang;
  592.     if (ang == 1)
  593. /*
  594.  *  Vertical
  595.  */
  596.     fprintf (outfile, "DI0,1;\n");
  597.     else
  598. /*
  599.  * Horizontal
  600.  */
  601.     fprintf (outfile, "DI1,0;\n");
  602.     return TRUE;
  603. }
  604.  
  605. int
  606. HPGL2_text_angle (ang)
  607.     int             ang;
  608. {
  609. /*
  610.  * If in Polyline Encoded command, leave Polyline Encoded command
  611.  */
  612.     if (HPGL2_in_pe) {
  613.     fputs (";", outfile);
  614.     HPGL2_in_pe = 0;
  615.     }
  616.     if (ang == 1)
  617. /*
  618.  *  Vertical
  619.  */
  620.     fprintf (outfile, "DI0,1");
  621.     else
  622. /*
  623.  * Horizontal
  624.  */
  625.     fprintf (outfile, "DI1,0");
  626.     HPGL_ang = ang;
  627.     return TRUE;
  628. }
  629.  
  630. HPGL_reset ()
  631. {
  632. /*
  633.  * I am not sure that "PG" is a command in HPGL.
  634.     fputs ("PG;", outfile);
  635.  */
  636. }
  637.  
  638. HPGL2_reset ()
  639. {
  640. /*
  641.  * Park the pen
  642.  * Advance a page
  643.  * End with ";"
  644.  */
  645.     fputs ("SP0PG;\n", outfile);
  646. }
  647.  
  648. PCL_reset ()
  649. {
  650. /*
  651.  * Return to PCL mode
  652.  * Printer reset (conditional eject)
  653.  */
  654.     fputs ("\033%0A\033E\n", outfile);
  655. }
  656.  
  657. HPGL2_justify_text (just)
  658.     int             just;
  659. {
  660. /*
  661.  * If in Polyline Encoded command, leave Polyline Encoded command
  662.  */
  663.     if (HPGL2_in_pe) {
  664.     fputs (";\n", outfile);
  665.     HPGL2_in_pe = 0;
  666.     }
  667.     switch (just) {
  668.     case LEFT:
  669.     fputs ("LO1", outfile);
  670.     break;
  671.     case CENTRE:
  672.     fputs ("LO4", outfile);
  673.     break;
  674.     case RIGHT:
  675.     fputs ("LO7", outfile);
  676.     break;
  677.     default:
  678.     return 0;
  679.     }
  680.     return 1;
  681. }
  682.  
  683.