home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Plotting / aa_Intel_Only / Gnuplot / GnuplotSource / term / tpic.trm < prev    next >
Encoding:
Text File  |  1995-06-12  |  25.3 KB  |  961 lines

  1. /*
  2.  * $Id: tpic.trm,v 1.5 1993/05/18 03:58:18 davis Exp $
  3.  */
  4.  
  5. /* GNUPLOT - tpic.trm */
  6. /*
  7.  * Copyright (C) 1990 - 1993   
  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.  *   The tpic \specials (version 2.2) for LaTeX. 
  25.  *
  26.  * AUTHORS
  27.  *   Oh-Yeah?   3 Sep. 1992 (closely following eepic.trm by David Kotz)
  28.  *   A. Woo     5 Oct. 1992 (removed ansi prototypes for braindead compilers)
  29.  *
  30.  * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
  31.  * 
  32.  */
  33. /*
  34.  *  This file contains the tpic terminal driver for use with LaTeX. 
  35.  *  This is an alternative to the latex and eepic drivers. You need 
  36.  *  a printer driver that supports the tpic \specials version 2.2.
  37.  *
  38.  * Comparison with the eepic driver (eepic.trm):
  39.  *  Merits
  40.  *    - More point and line types
  41.  *    - Options to change point size, linewidth, dot & dash intervals
  42.  *    - Dotted and dashed lines for high-sample-rate curves (but may
  43.  *      depend on tpic (da & dt) implementation of your dvi driver :-)
  44.  *    - Overlapped points made fancier by tpic shading facility
  45.  *    - Optional comments for trimming figure margins
  46.  *    - No need for epic and eepic macros
  47.  *  Drawback
  48.  *    - You cannot use eepicemu macro for non-tpic-support dvi drivers
  49.  *
  50.  * LATEX must also be defined.
  51.  */
  52.  
  53.  
  54. /* These parameters can be modified as you like, through options.  Say 
  55.    "set terminal tpic <pointsize> <linewidth> <interval>".  <pointsize> 
  56.    and <linewidth> are integers in milli-inches; <interval> is a float 
  57.    in inches.  If non-positive value is specified, the default (below) 
  58.    is chosen. 
  59. */
  60. static int tpic_pointsize   =  40; /* min point radius   (in milli-inches) */
  61. static int tpic_linewidth   =   6; /* min line thickness (in milli-inches) */
  62. static double tpic_interval = 0.1; /* min dot & dash intervals (in inches) */
  63.  
  64. /* ARROWS: same code as for LATEX */
  65. /* static void best\_latex\_arrow(int sx, int sy, int ex, int ey, int who, 
  66.     TBOOLEAN head); figure out the best arrow. in latex.trm */
  67. static void best_latex_arrow();
  68.  
  69. /* all prototypes ... */
  70. int TPIC_options(); /* get size options */
  71. int TPIC_init();
  72. int TPIC_reset();
  73. int TPIC_text();
  74. /* TBOOLEAN TPIC_scale(double xs, double ys);  scaling factors */
  75. TBOOLEAN TPIC_scale();
  76. int TPIC_graphics();
  77. /* int TPIC_move(unsigned int x, unsigned int y);
  78. int TPIC_vector(unsigned int ux, unsigned int uy); */
  79. int TPIC_move();
  80. int TPIC_vector();
  81. static void tpic_startline();  /* private */
  82. static void tpic_endline();  /* private */
  83. /* static void tpic_pushpath(unsigned int x, unsigned int y); /* private */
  84. static void tpic_pushpath();
  85. static void tpic_scanpath();
  86. /* int TPIC_linetype(int linetype);
  87. int TPIC_put_text(int x, int y, char *str); /* ref point and text */
  88. int TPIC_linetype();
  89. int TPIC_put_text();
  90. /* TBOOLEAN TPIC_text_angle(int angle);
  91. TBOOLEAN TPIC_justify_text(enum JUSTIFY mode); */
  92. TBOOLEAN TPIC_text_angle();
  93. TBOOLEAN TPIC_justify_text();
  94. /* int TPIC_point(unsigned int x, unsigned int y, int number); */
  95. int TPIC_point();
  96. /* int TPIC_arrow(int sx, int sy, int ex, int ey, TBOOLEAN head); */
  97. int TPIC_arrow();
  98. /* void tpic_diamond(int size); */
  99. void tpic_diamond();
  100. /* void tpic_plus(int size); */
  101. void tpic_plus();
  102. /* void tpic_box(int size); */
  103. void tpic_box();
  104. /* void tpic_times(int size); */
  105. void tpic_times();
  106. /* void tpic_triangle(int size); */
  107. void tpic_triangle();
  108. /* void tpic_star(int size); */
  109. void tpic_star();
  110. /* void tpic_hexagon(int size); */
  111. void tpic_hexagon();
  112. /* void tpic_circle(int size); */
  113. void tpic_circle();
  114. /* void tpic_doublecircle(int size); */
  115. void tpic_doublecircle();
  116. /* void tpic_vercircle(int size); /* circle with | */
  117. void tpic_vercircle(); /* circle with | */
  118. /* void tpic_horcircle(int size); /* circle with - */
  119. void tpic_horcircle(); /* circle with - */
  120. /* void tpic_pluscircle(int size); /* circle with + */
  121. void tpic_pluscircle(); /* circle with + */
  122. /* void tpic_timescircle(int size); /* circle with times */
  123. void tpic_timescircle(); /* circle with times */
  124. /* void tpic_starcircle(int size); /* circle with star */
  125. void tpic_starcircle(); /* circle with star */
  126. /* void tpic_dotcircle(int size); /* circle with dot (black circle) */
  127. void tpic_dotcircle(); /* circle with dot (black circle) */
  128. /* void tpic_diamondcircle(int size); /* circle with black diamond */
  129. void tpic_diamondcircle(); /* circle with black diamond */
  130. /* void tpic_boxcircle(int size); /* circle with black box */
  131. void tpic_boxcircle(); /* circle with black box */
  132. /* void tpic_trianglecircle(int size); /* circle with black triangle */
  133. void tpic_trianglecircle(); /* circle with black triangle */
  134. /* void tpic_hexagoncircle(int size); /* circle with black hexagon */
  135. void tpic_hexagoncircle(); /* circle with black hexagon */
  136. /* void tpic_plustimescircle(int size); /* no more idea ... with plus & times */
  137. void tpic_plustimescircle(); /* no more idea ... with plus & times */
  138. /* void tpic_abspath(unsigned int x, unsigned int y); /* absolute coord */
  139. void tpic_abspath(); /* absolute coord */
  140. /* void tpic_path(int x, int y); */
  141. void tpic_path();
  142. /* void tpic_flush(void); */
  143. void tpic_flush();
  144. /* void tpic_arc(int radius); /* actually, draw a full circle */
  145. void tpic_arc(); /* actually, draw a full circle */
  146. /* void tpic_shade(double grayscale); */
  147. void tpic_shade();
  148. /* void tpic_pen(int thickness); */
  149. void tpic_pen();
  150. /* void tpic_dottedflush(double interval); */
  151. void tpic_dottedflush();
  152. /* void tpic_dashedflush(double interval); */
  153. void tpic_dashedflush();
  154.  
  155. #define TPIC_UNIT 0.001 /* tpic \specials unit in inches (1 milli-inch) */
  156. /* 5 inches wide by 3 inches high (default) */
  157. #define TPIC_XMAX (unsigned int) (5 / TPIC_UNIT)
  158. #define TPIC_YMAX (unsigned int) (3 / TPIC_UNIT)
  159. #define TPIC_PTS_PER_UNIT (72.27 * TPIC_UNIT)
  160. #define TPIC_HTIC  (unsigned int) ( 5.0 / TPIC_PTS_PER_UNIT) /* 5pt */
  161. #define TPIC_VTIC  (unsigned int) ( 5.0 / TPIC_PTS_PER_UNIT) /* 5pt */
  162. #define TPIC_HCHAR (unsigned int) ( 5.3 / TPIC_PTS_PER_UNIT) /* 5.3pt */
  163. #define TPIC_VCHAR (unsigned int) (11.0 / TPIC_PTS_PER_UNIT) /* 11pt */
  164.  
  165. typedef enum {tpic_none, tpic_white, tpic_gray, tpic_black} tpic_shadestyle;
  166. typedef enum {tpic_nosize, tpic_small, tpic_medium, tpic_large} tpic_size;
  167. /* typedef void (*tpic_function)(int size); */
  168. typedef void (*tpic_function)();
  169. typedef struct {
  170.     tpic_shadestyle shadestyle;
  171.     tpic_size size;
  172.     tpic_function function;
  173. } tpic_point_info;
  174.  
  175. /* POINTS */
  176. static tpic_point_info tpic_point[] = {
  177.     {tpic_white, tpic_medium, tpic_diamond},
  178.     {tpic_none,  tpic_medium, tpic_plus},
  179.     {tpic_white, tpic_medium, tpic_box},
  180.     {tpic_none,  tpic_medium, tpic_times},
  181.     {tpic_white, tpic_medium, tpic_triangle},
  182.     {tpic_none,  tpic_medium, tpic_star},
  183.     {tpic_white, tpic_small,  tpic_circle},
  184.     {tpic_white, tpic_medium, tpic_circle},
  185.     {tpic_white, tpic_large,  tpic_circle},
  186.     {tpic_black, tpic_small,  tpic_circle},
  187.     {tpic_black, tpic_medium, tpic_circle},
  188.     {tpic_black, tpic_large,  tpic_circle},
  189.     {tpic_black, tpic_medium, tpic_diamond},
  190.     {tpic_black, tpic_medium, tpic_box},
  191.     {tpic_black, tpic_medium, tpic_triangle},
  192.     {tpic_white, tpic_medium, tpic_hexagon},
  193.     {tpic_black, tpic_medium, tpic_hexagon},
  194.     {tpic_white, tpic_medium, tpic_doublecircle},
  195.     {tpic_white, tpic_medium, tpic_vercircle},
  196.     {tpic_white, tpic_medium, tpic_horcircle},
  197.     {tpic_white, tpic_medium, tpic_pluscircle},
  198.     {tpic_white, tpic_medium, tpic_timescircle},
  199.     {tpic_white, tpic_medium, tpic_starcircle},
  200.     {tpic_black, tpic_medium, tpic_doublecircle},
  201.     {tpic_white, tpic_medium, tpic_dotcircle},
  202.     {tpic_white, tpic_medium, tpic_diamondcircle},
  203.     {tpic_white, tpic_medium, tpic_boxcircle},
  204.     {tpic_white, tpic_medium, tpic_trianglecircle},
  205.     {tpic_white, tpic_medium, tpic_hexagoncircle},
  206.     {tpic_white, tpic_medium, tpic_plustimescircle}
  207. };
  208.  
  209. typedef enum {tpic_solid, tpic_dotted, tpic_dashed, 
  210.     tpic_dashed_sdot, tpic_dashed_ddot} tpic_linestyle;
  211. typedef struct {
  212.     tpic_size thickness, interval;
  213.     tpic_linestyle linestyle;
  214. } tpic_line_info;
  215.  
  216. /* LINES */
  217. static tpic_line_info tpic_line[] = {
  218.     {tpic_medium, tpic_nosize, tpic_solid},  /* -2 border */
  219.     {tpic_small,  tpic_small,  tpic_dashed}, /* -1 axes */
  220.     {tpic_small,  tpic_nosize, tpic_solid},
  221.     {tpic_medium, tpic_nosize, tpic_solid},
  222.     {tpic_large,  tpic_nosize, tpic_solid},
  223.     {tpic_small,  tpic_small,  tpic_dotted},
  224.     {tpic_medium, tpic_small,  tpic_dotted},
  225.     {tpic_large,  tpic_small,  tpic_dotted},
  226.     {tpic_small,  tpic_small,  tpic_dashed},
  227.     {tpic_medium, tpic_small,  tpic_dashed},
  228.     {tpic_large,  tpic_small,  tpic_dashed},
  229.     {tpic_small,  tpic_small,  tpic_dashed_sdot}, /* dash with single dots */
  230.     {tpic_medium, tpic_small,  tpic_dashed_sdot},
  231.     {tpic_large,  tpic_small,  tpic_dashed_sdot},
  232.     {tpic_small,  tpic_small,  tpic_dashed_ddot}, /* dash with double dots */
  233.     {tpic_medium, tpic_small,  tpic_dashed_ddot},
  234.     {tpic_large,  tpic_small,  tpic_dashed_ddot},
  235.     {tpic_small,  tpic_medium, tpic_dotted},
  236.     {tpic_medium, tpic_medium, tpic_dotted},
  237.     {tpic_large,  tpic_medium, tpic_dotted},
  238.     {tpic_small,  tpic_medium, tpic_dashed},
  239.     {tpic_medium, tpic_medium, tpic_dashed},
  240.     {tpic_large,  tpic_medium, tpic_dashed},
  241.     {tpic_small,  tpic_medium, tpic_dashed_sdot},
  242.     {tpic_medium, tpic_medium, tpic_dashed_sdot},
  243.     {tpic_large,  tpic_medium, tpic_dashed_sdot},
  244.     {tpic_small,  tpic_medium, tpic_dashed_ddot},
  245.     {tpic_medium, tpic_medium, tpic_dashed_ddot},
  246.     {tpic_large,  tpic_medium, tpic_dashed_ddot},
  247.     {tpic_small,  tpic_large,  tpic_dotted},
  248.     {tpic_medium, tpic_large,  tpic_dotted},
  249.     {tpic_large,  tpic_large,  tpic_dotted},
  250.     {tpic_small,  tpic_large,  tpic_dashed},
  251.     {tpic_medium, tpic_large,  tpic_dashed},
  252.     {tpic_large,  tpic_large,  tpic_dashed},
  253.     {tpic_small,  tpic_large,  tpic_dashed_sdot},
  254.     {tpic_medium, tpic_large,  tpic_dashed_sdot},
  255.     {tpic_large,  tpic_large,  tpic_dashed_sdot},
  256.     {tpic_small,  tpic_large,  tpic_dashed_ddot},
  257.     {tpic_medium, tpic_large,  tpic_dashed_ddot},
  258.     {tpic_large,  tpic_large,  tpic_dashed_ddot}
  259. };
  260.  
  261. /* int TPIC_options(void) /* get size options */
  262. int TPIC_options() /* get size options */
  263. {
  264. /*
  265.     extern struct value *const_express(struct value *valptr);
  266.     extern double real(struct value *val);
  267.     */
  268.     extern struct value *const_express();
  269.     extern double real();
  270.     struct value a;
  271.     int pointsize, linewidth;
  272.     double interval;
  273.  
  274.     if (!END_OF_COMMAND) {
  275.         pointsize = (int)real(const_express(&a));
  276.         if (pointsize > 0) tpic_pointsize = pointsize;
  277.     }
  278.  
  279.     if (!END_OF_COMMAND) {
  280.         linewidth = (int)real(const_express(&a));
  281.         if (linewidth > 0) tpic_linewidth = linewidth;
  282.     }
  283.  
  284.     if (!END_OF_COMMAND) {
  285.         interval = (double)real(const_express(&a));
  286.         if (interval > 0) tpic_interval = interval;
  287.     }
  288.  
  289.     sprintf(term_options, "%d %d %f", tpic_pointsize, tpic_linewidth, 
  290.         tpic_interval);
  291.     return(0);
  292. }
  293.  
  294. static unsigned int tpic_posx; /* current position */
  295. static unsigned int tpic_posy;
  296. static int tpic_point_types;
  297. static int tpic_numlines;
  298.  
  299. /* int TPIC_init(void) */
  300. int TPIC_init()
  301. {
  302.     tpic_point_types = sizeof(tpic_point) / sizeof(tpic_point[0]);
  303.     tpic_numlines = sizeof(tpic_line) / sizeof(tpic_line[0]);
  304.  
  305.     tpic_posx = tpic_posy = 0;
  306.     TPIC_linetype(-1);
  307.     fprintf(outfile, "%% GNUPLOT: LaTeX picture using tpic \\specials\n");
  308.     fprintf(outfile, "%%          with %d point types and %d line types\n", 
  309.         tpic_point_types, tpic_numlines - 2);
  310.     fprintf(outfile, 
  311.         "%% Options: pointsize = %d, linewidth = %d, interval = %f\n", 
  312.         tpic_pointsize, tpic_linewidth, tpic_interval);
  313.     fprintf(outfile, "%% To change above options, say:\n");
  314.     fprintf(outfile, 
  315.     "%% set terminal tpic pointsize_value linewidth_value interval_value\n");
  316.     fprintf(outfile, 
  317.         "%% (pointsize and linewidth - integers in milli-inches.\n");
  318.     fprintf(outfile, 
  319.         "%%  interval - a float in inches.  If zero is specified, \n");
  320.     fprintf(outfile, 
  321.         "%%  the default value is chosen.)\n");
  322.  
  323.     fprintf(outfile, "\\setlength{\\unitlength}{%fin}%%\n", TPIC_UNIT);
  324.     return(0);
  325. }
  326.  
  327. /* int TPIC_reset(void) */
  328. int TPIC_reset()
  329. {
  330.     tpic_endline();
  331.     tpic_posx = tpic_posy = 0;
  332.     return(0);
  333. }
  334.  
  335. /* int TPIC_text(void) */
  336. int TPIC_text()
  337. {
  338.     tpic_endline();
  339.     fprintf(outfile, "\\end{picture}\n");
  340.     return(0);
  341. }
  342.  
  343. /* TBOOLEAN TPIC_scale(double xs, double ys) /* scaling factors */
  344. TBOOLEAN TPIC_scale(xs,ys)
  345. double xs; double ys; /* scaling factors */
  346. {
  347.     register struct termentry *t = &term_tbl[term];
  348.  
  349.     /* we change the table for use in graphics.c and TPIC_graphics */
  350.     t->xmax = (unsigned int)(TPIC_XMAX * xs);
  351.     t->ymax = (unsigned int)(TPIC_YMAX * ys);
  352.     return(TRUE);
  353. }
  354.  
  355. /* int TPIC_graphics(void) */
  356. int TPIC_graphics()
  357. {
  358.     register struct termentry *t = &term_tbl[term];
  359.     int left, right, top, bottom; /* margins */
  360.     static char begin[] = "%s\\begin{picture}(%d,%d)(%d,%d)%% %s\n";
  361.  
  362.     fprintf(outfile, begin, "", t->xmax, t->ymax, 0, 0, "");
  363.  
  364.     /* the following is dependent on boundary() function in graphics.c */
  365.     left = TPIC_HCHAR * 12;
  366.     right = TPIC_HCHAR * 2 + TPIC_HTIC;
  367.     bottom = TPIC_VCHAR * 7 / 2 + 1;
  368.     top = TPIC_VCHAR * 5 / 2 - 1;
  369.     fprintf(outfile, begin, "%% ", t->xmax - left, t->ymax, left, 0, 
  370.         "trim left margin");
  371.     fprintf(outfile, begin, "%% ", t->xmax - right, t->ymax, 0, 0, 
  372.         "trim right margin");
  373.     fprintf(outfile, begin, "%% ", t->xmax - left - right, t->ymax, left, 0, 
  374.         "trim left & right margins");
  375.     fprintf(outfile, begin, "%% ", t->xmax, t->ymax - top, 0, 0, 
  376.         "trim top margin");
  377.     fprintf(outfile, begin, "%% ", t->xmax, t->ymax - bottom, 0, bottom, 
  378.         "trim bottom margin");
  379.     fprintf(outfile, begin, "%% ", t->xmax, t->ymax - top - bottom, 0, bottom,
  380.         "trim top & bottom margins");
  381.  
  382.     fprintf(outfile, "\\tenrm%%\n");
  383.     return(0);
  384. }
  385.  
  386. /* int TPIC_move(unsigned int x, unsigned int y) */
  387. int TPIC_move(x,y)
  388. unsigned int x; unsigned int y;
  389. {
  390.     tpic_endline();
  391.     tpic_posx = x;
  392.     tpic_posy = y;
  393.     return(0);
  394. }
  395.  
  396. #define TPIC_LINEMAX 100 /* max value for linecount */
  397. static TBOOLEAN tpic_inline = FALSE; /* are we in the middle of a line */
  398. static int tpic_linecount = 0; /* number of points in line so far */
  399.  
  400. /* int TPIC_vector(unsigned int ux, unsigned int uy) */
  401. int TPIC_vector(ux,uy)
  402. unsigned int ux; unsigned int uy;
  403. {
  404.     if (!tpic_inline) {
  405.         tpic_startline();
  406.     } else if (tpic_linecount >= TPIC_LINEMAX) {
  407.         /* Even though we are in middle of a path, we may start a new path 
  408.         command once in a while; if they are too long, latex will choke. */
  409.         tpic_endline();
  410.         tpic_startline();
  411.     }
  412.     tpic_pushpath(ux, uy);
  413.     tpic_posx = ux;
  414.     tpic_posy = uy;
  415.     return(0);
  416. }
  417.  
  418. static int tpic_linetype; /* current line type */
  419.  
  420. /* static void tpic_startline(void) /* private */
  421. static void tpic_startline() /* private */
  422. {
  423.     int thickness;
  424.  
  425.     tpic_inline = TRUE;
  426.     switch (tpic_line[tpic_linetype + 2].thickness) {
  427.     case tpic_small:
  428.         thickness = tpic_linewidth;
  429.         break;
  430.     case tpic_medium:
  431.         thickness = (int)(tpic_linewidth * 3);
  432.         break;
  433.     case tpic_large:
  434.         thickness = (int)(tpic_linewidth * 5);
  435.         break;
  436.     }
  437.     tpic_pen(thickness);
  438.     tpic_linecount = 0;
  439.     tpic_pushpath(tpic_posx, tpic_posy);
  440.     return;
  441. }
  442.  
  443. /* static void tpic_endline(void) /* private */
  444. static void tpic_endline() /* private */
  445. {
  446.     double interval;
  447.  
  448.     if (tpic_inline) {
  449.         tpic_scanpath(); /* draw actually */
  450.         switch (tpic_line[tpic_linetype + 2].interval) {
  451.         case tpic_small:
  452.             interval = tpic_interval;
  453.             break;
  454.         case tpic_medium:
  455.             interval = tpic_interval * 2;
  456.             break;
  457.         case tpic_large:
  458.             interval = tpic_interval * 3;
  459.             break;
  460.         case tpic_nosize:
  461.             break;
  462.         }
  463.         switch (tpic_line[tpic_linetype + 2].linestyle) {
  464.         case tpic_solid:
  465.             tpic_flush();
  466.             break;
  467.         case tpic_dotted:
  468.             tpic_dottedflush(interval);
  469.             break;
  470.         case tpic_dashed:
  471.             tpic_dashedflush(interval);
  472.             break;
  473.         case tpic_dashed_sdot: /* dashed with single dots in between */
  474.             tpic_dashedflush(interval);
  475.             tpic_scanpath(); /* draw again */
  476.             tpic_dottedflush(interval / 2);
  477.             break;
  478.         case tpic_dashed_ddot: /* dashed with double dots in between */
  479.             tpic_dashedflush(interval);
  480.             tpic_scanpath(); /* draw again */
  481.             tpic_dottedflush(interval / 3);
  482.             break;
  483.         }
  484.         tpic_inline = FALSE;
  485.     }
  486.     return;
  487. }
  488.  
  489. /* private: stack functions */
  490. static unsigned int pathpoint[TPIC_LINEMAX][2]; /* point stack */
  491.  
  492. /* static void tpic_pushpath(unsigned int x, unsigned int y) /* private */
  493. static void tpic_pushpath(x,y)
  494. unsigned int x; unsigned int y; /* private */
  495. {
  496.     if (tpic_linecount < TPIC_LINEMAX) {
  497.         pathpoint[tpic_linecount][0] = x;
  498.         pathpoint[tpic_linecount][1] = y;
  499.         tpic_linecount++;
  500.     }
  501.     return;
  502. }
  503.  
  504. /* static void tpic_scanpath(void) */
  505. static void tpic_scanpath()
  506. {
  507.     int i;
  508.  
  509.     for (i = 0; i < tpic_linecount; i++)
  510.         tpic_abspath(pathpoint[i][0], pathpoint[i][1]);
  511.     return;
  512. }
  513.  
  514. /* int TPIC_linetype(int linetype) */
  515. int TPIC_linetype(linetype)
  516. int linetype;
  517. {
  518.     tpic_endline();
  519.     if (linetype >= tpic_numlines - 2) linetype %= (tpic_numlines - 2);
  520.     tpic_linetype = linetype;
  521.     return(0);
  522. }
  523.  
  524. static int tpic_angle = 0; /* 0 = horizontal, 1 = vertical */
  525. static enum JUSTIFY tpic_justify = LEFT;
  526.  
  527. /* int TPIC_put_text(int x, int y, char *str) /* ref point and text */
  528. int TPIC_put_text(x,y,str)
  529. int x; int y; char *str; /* ref point and text */
  530. {
  531.     char *justify;
  532.  
  533.     tpic_endline();
  534.     fprintf(outfile, "\\put(%d,%d)", x, y);
  535.  
  536.     switch (tpic_angle) {
  537.     case 0: /* horizontal */
  538.         switch (tpic_justify) {
  539.         case LEFT:
  540.             justify = "[l]";
  541.             break;
  542.         case CENTRE:
  543.             justify = "";
  544.             break;
  545.         case RIGHT:
  546.             justify = "[r]";
  547.             break;
  548.         }
  549.         fprintf(outfile, "{\\makebox(0,0)%s{%s}}\n", justify, str);
  550.         break;
  551.     case 1: /* vertical */
  552.         /* we can't really write text vertically, but will put the ylabel 
  553.         centred at the left of the plot, and then we'll make a \shortstack */
  554.         switch (tpic_justify) {
  555.         case LEFT:
  556.             justify = "[lb]";
  557.             break;
  558.         case CENTRE:
  559.             justify = "[l]";
  560.             break;
  561.         case RIGHT:
  562.             justify = "[lt]";
  563.             break;
  564.         }
  565.         fprintf(outfile, "{\\makebox(0,0)%s{\\shortstack{%s}}}\n", 
  566.             justify, str);
  567.         break;
  568.     }
  569.     return(0);
  570. }
  571.  
  572. /* TBOOLEAN TPIC_text_angle(int angle) */
  573. TBOOLEAN TPIC_text_angle(angle)
  574. int angle;
  575. {
  576.     tpic_angle = angle;
  577.     return(TRUE);
  578. }
  579.  
  580. /* TBOOLEAN TPIC_justify_text(enum JUSTIFY mode) */
  581. TBOOLEAN TPIC_justify_text(mode)
  582. enum JUSTIFY mode;
  583. {
  584.     tpic_justify = mode;
  585.     return(TRUE);
  586. }
  587.  
  588. /* int TPIC_point(unsigned int x, unsigned int y, int number) */
  589. int TPIC_point(x,y,number)
  590. unsigned int x; unsigned int y; int number;
  591. {
  592.     int size;
  593.  
  594.     TPIC_move(x, y);
  595.  
  596.     /* Print the character defined by 'number'; number < 0 means 
  597.     to use a dot, otherwise one of the defined points. */
  598.  
  599.     fprintf(outfile, "\\put(%d,%d){", x, y); /* start putting */
  600.  
  601.     if (number < 0) {
  602.         fprintf(outfile, "\\rule{.1pt}{.1pt}"); /* tiny dot */
  603.     } else {
  604.         number %= tpic_point_types;
  605.         switch (tpic_point[number].shadestyle) {
  606.         case tpic_white:
  607.             tpic_pen(tpic_linewidth); /* set it thin */
  608.             tpic_shade(0.0);
  609.             break;
  610.         case tpic_gray:
  611.             tpic_pen(tpic_linewidth);
  612.             tpic_shade(0.5);
  613.             break;
  614.         case tpic_black:
  615.             tpic_pen(tpic_linewidth);
  616.             tpic_shade(1.0);
  617.             break;
  618.         case tpic_none:
  619.             tpic_pen(tpic_linewidth * 3); /* set it thick */
  620.             break;
  621.         }
  622.         switch (tpic_point[number].size) {
  623.         case tpic_small:
  624.             size = tpic_pointsize;
  625.             break;
  626.         case tpic_medium:
  627.             size = (int)(tpic_pointsize * 1.4142);
  628.             break;
  629.         case tpic_large:
  630.             size = (int)(tpic_pointsize * 2.0);
  631.             break;
  632.         }
  633.         (tpic_point[number].function)(size);
  634.     }
  635.  
  636.     fprintf(outfile, "}%%\n"); /* end putting */
  637.     return(0);
  638. }
  639.  
  640. /* int TPIC_arrow(int sx, int sy, int ex, int ey, TBOOLEAN head) */
  641. int TPIC_arrow(sx,sy,ex,ey,head)
  642. int sx; int sy; int ex; int ey; TBOOLEAN head;
  643. {
  644.     best_latex_arrow(sx, sy, ex, ey, 1, head); /* call latex routine */
  645.     tpic_posx = ex;
  646.     tpic_posy = ey;
  647.     return(0);
  648. }
  649.  
  650. /* private: draw points with tpic commands */
  651.  
  652. /* void tpic_diamond(int size) */
  653. void tpic_diamond(size)
  654. int size;
  655. {
  656.     size = (int)(size * 1.4142); /* spread by sqrt(2) */
  657.  
  658.     tpic_path(0, size);
  659.     tpic_path(-size, 0);
  660.     tpic_path(0, -size);
  661.     tpic_path(size, 0);
  662.     tpic_path(0, size);
  663.     tpic_flush();
  664.     return;
  665. }
  666.  
  667. /* void tpic_plus(int size) */
  668. void tpic_plus(size)
  669. int size;
  670. {
  671.     tpic_path(0, size);
  672.     tpic_path(0, -size);
  673.     tpic_flush();
  674.     tpic_path(size, 0);
  675.     tpic_path(-size, 0);
  676.     tpic_flush();
  677.     return;
  678. }
  679.  
  680. /* void tpic_box(int size) */
  681. void tpic_box(size)
  682. int size;
  683. {
  684.     tpic_path(size, size);
  685.     tpic_path(-size, size);
  686.     tpic_path(-size, -size);
  687.     tpic_path(size, -size);
  688.     tpic_path(size, size);
  689.     tpic_flush();
  690.     return;
  691. }
  692.  
  693. /* void tpic_times(int size) */
  694. void tpic_times(size)
  695. int size;
  696. {
  697.     size = (int)(size / 1.4142); /* reduce by sqrt(2) */
  698.  
  699.     tpic_path(size, size);
  700.     tpic_path(-size, -size);
  701.     tpic_flush();
  702.     tpic_path(size, -size);
  703.     tpic_path(-size, size);
  704.     tpic_flush();
  705.     return;
  706. }
  707.  
  708. /* void tpic_triangle(int size) */
  709. void tpic_triangle(size)
  710. int size;
  711. {
  712.     int x;
  713.  
  714.     size = (int)(size / 1.6119); /* reduce by sqrt(3 * sqrt(3) / 2) */
  715.     x = (int)(size * 1.7321);
  716.  
  717.     tpic_path(0, -size * 2);
  718.     tpic_path(-x, size);
  719.     tpic_path(x, size);
  720.     tpic_path(0, -size * 2);
  721.     tpic_flush();
  722.     return;
  723. }
  724.  
  725. /* void tpic_star(int size) */
  726. void tpic_star(size)
  727. int size;
  728. {
  729.     int x;
  730.  
  731.     size = (int)(size / 2); /* reduce by 2 */
  732.     x = (int)(size * 1.7321);
  733.  
  734.     tpic_path(0, size * 2);
  735.     tpic_path(0, -size * 2);
  736.     tpic_flush();
  737.     tpic_path(x, size);
  738.     tpic_path(-x, -size);
  739.     tpic_flush();
  740.     tpic_path(x, -size);
  741.     tpic_path(-x, size);
  742.     tpic_flush();
  743.     return;
  744. }
  745.  
  746. /* void tpic_hexagon(int size) */
  747. void tpic_hexagon(size)
  748. int size;
  749. {
  750.     int x;
  751.  
  752.     size = (int)(size / 2); /* reduce by 2 */
  753.     x = (int)(size * 1.7321);
  754.  
  755.     tpic_path(0, size * 2);
  756.     tpic_path(-x, size);
  757.     tpic_path(-x, -size);
  758.     tpic_path(0, -size * 2);
  759.     tpic_path(x, -size);
  760.     tpic_path(x, size);
  761.     tpic_path(0, size * 2);
  762.     tpic_flush();
  763.     return;
  764. }
  765.  
  766. /* void tpic_circle(int size) */
  767. void tpic_circle(size)
  768. int size;
  769. {
  770.     tpic_arc(size);
  771.     return;
  772. }
  773.  
  774. /* void tpic_doublecircle(int size) */
  775. void tpic_doublecircle(size)
  776. int size;
  777. {
  778.     tpic_arc(size);
  779.     tpic_shade(0.0);
  780.     tpic_arc(size / 2);
  781.     return;
  782. }
  783.  
  784. /* void tpic_vercircle(int size) /* circle with | */
  785. void tpic_vercircle(size)
  786. int size; /* circle with | */
  787. {
  788.     tpic_arc(size);
  789.     tpic_path(0, size);
  790.     tpic_path(0, -size);
  791.     tpic_flush();
  792.     return;
  793. }
  794.  
  795. /* void tpic_horcircle(int size) /* circle with - */
  796. void tpic_horcircle(size)
  797. int size; /* circle with - */
  798. {
  799.     tpic_arc(size);
  800.     tpic_path(size, 0);
  801.     tpic_path(-size, 0);
  802.     tpic_flush();
  803.     return;
  804. }
  805.  
  806. /* void tpic_pluscircle(int size) /* circle with + */
  807. void tpic_pluscircle(size)
  808. int size; /* circle with + */
  809. {
  810.     tpic_arc(size);
  811.     tpic_plus(size);
  812.     return;
  813. }
  814.  
  815. /* void tpic_timescircle(int size) /* circle with times */
  816. void tpic_timescircle(size)
  817. int size; /* circle with times */
  818. {
  819.     tpic_arc(size);
  820.     tpic_times(size);
  821.     return;
  822. }
  823.  
  824. /* void tpic_starcircle(int size) /* circle with star */
  825. void tpic_starcircle(size)
  826. int size; /* circle with star */
  827. {
  828.     tpic_arc(size);
  829.     tpic_star(size);
  830.     return;
  831. }
  832.  
  833. /* void tpic_dotcircle(int size) /* circle with dot (black circle) */
  834. void tpic_dotcircle(size)
  835. int size; /* circle with dot (black circle) */
  836. {
  837.     tpic_arc(size);
  838.     tpic_shade(1.0);
  839.     tpic_arc(size / 2);
  840.     return;
  841. }
  842.  
  843. /* void tpic_diamondcircle(int size) /* not enough? circle with black diamond */
  844. void tpic_diamondcircle(size)
  845. int size; /* not enough? circle with black diamond */
  846. {
  847.     tpic_arc(size);
  848.     tpic_shade(1.0);
  849.     tpic_diamond((int)(size / 1.5));
  850.     return;
  851. }
  852.  
  853. /* void tpic_boxcircle(int size) /* need more? circle with black box */
  854. void tpic_boxcircle(size)
  855. int size; /* need more? circle with black box */
  856. {
  857.     tpic_arc(size);
  858.     tpic_shade(1.0);
  859.     tpic_box((int)(size / 1.5));
  860.     return;
  861. }
  862.  
  863. /* void tpic_trianglecircle(int size) /* circle with black triangle */
  864. void tpic_trianglecircle(size)
  865. int size; /* circle with black triangle */
  866. {
  867.     tpic_arc(size);
  868.     tpic_shade(1.0);
  869.     tpic_triangle((int)(size / 1.5));
  870.     return;
  871. }
  872.  
  873. /* void tpic_hexagoncircle(int size) /* how about circle with black hexagon? */
  874. void tpic_hexagoncircle(size)
  875. int size; /* how about circle with black hexagon? */
  876. {
  877.     tpic_arc(size);
  878.     tpic_shade(1.0);
  879.     tpic_hexagon((int)(size / 1.2));
  880.     return;
  881. }
  882.  
  883. /* void tpic_plustimescircle(int size) /* no more idea ... with plus & times */
  884. void tpic_plustimescircle(size)
  885. int size; /* no more idea ... with plus & times */
  886. {
  887.     tpic_arc(size);
  888.     tpic_plus(size);
  889.     tpic_times(size);
  890.     return;
  891. }
  892.  
  893. /* private: draw lines */
  894.  
  895. /* void tpic_abspath(unsigned int x, unsigned int y) /* absolute coord */
  896. void tpic_abspath(x,y)
  897. unsigned int x; unsigned int y; /* absolute coord */
  898. {
  899.     fprintf(outfile, "\\put(%u,%u){", x, y); /* start putting */
  900.     tpic_path(0, 0);
  901.     fprintf(outfile, "}%%\n"); /* end putting */
  902.     return;
  903. }
  904.  
  905. /* private: tpic primitive functions */
  906.  
  907. /* void tpic_path(int x, int y) */
  908. void tpic_path(x,y)
  909. int x; int y;
  910. {
  911.     fprintf(outfile, "\\special{pa %d %d}", x, y);
  912.     return;
  913. }
  914.  
  915. /* void tpic_flush(void) */
  916. void tpic_flush()
  917. {
  918.     fprintf(outfile, "\\special{fp}%%\n");
  919.     return;
  920. }
  921.  
  922. /* void tpic_arc(int radius) /* actually, draw a full circle */
  923. void tpic_arc(radius)
  924. int radius; /* actually, draw a full circle */
  925. {
  926.     fprintf(outfile, "\\special{ar 0 0 %d %d 0 7}", radius, radius);
  927.     return;
  928. }
  929.  
  930. /* void tpic_shade(double grayscale) */
  931. void tpic_shade(grayscale)
  932. double grayscale;
  933. {
  934.     fprintf(outfile, "\\special{sh %f}", grayscale);
  935.     return;
  936. }
  937.  
  938. /* void tpic_pen(int thickness) */
  939. void tpic_pen(thickness)
  940. int thickness;
  941. {
  942.     fprintf(outfile, "\\special{pn %d}", thickness);
  943.     return;
  944. }
  945.  
  946. /* void tpic_dottedflush(double interval) */
  947. void tpic_dottedflush(interval)
  948. double interval;
  949. {
  950.     fprintf(outfile, "\\special{dt %f}%%\n", interval);
  951.     return;
  952. }
  953.  
  954. /* void tpic_dashedflush(double interval) */
  955. void tpic_dashedflush(interval)
  956. double interval;
  957. {
  958.     fprintf(outfile, "\\special{da %f}%%\n", interval);
  959.     return;
  960. }
  961.