hpgl.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:10k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * HPGL Output
  3.  *
  4.  * Tom Quarles
  5.  */
  6. #define MAPX(state,x) ( (x) + P1X + state->clipminX )
  7. #define MAPY(state,y) ( MAXY - (y) + P1Y - state->clipminY)
  8. #include "copyright.h"
  9. #include "xgraph.h"
  10. #include "plotter.h"
  11. #include <stdio.h>
  12. #include <math.h>
  13. static void hpglText();
  14. static void hpglSeg();
  15. static void hpglDot();
  16. static void hpglEnd();
  17. static xgOut hpglInfo =
  18. {
  19.     D_COLOR, /* device characteristics */
  20.     MAXX, /* width */
  21.     MAXY, /* height */
  22.     200, /* border padding */
  23.     0, /* extra space around axis labels */
  24.     250, /* tick length - approx 1/4 inch */
  25.     50, /* spacing above legend lables */
  26.     0, /* axis font width */
  27.     0, /* axis font height */
  28.     0, /* title font width */
  29.     0, /* title font height */
  30.     1000000, /* maximum number of segments */
  31.     hpglText, /* text output function */
  32.     hpglSeg, /* segment  drawing function */
  33.     hpglDot, /* dot/marker drawing function */
  34.     hpglEnd, /* end of plot function */
  35.     NULL, /* userInfo */
  36. };
  37. typedef struct {
  38.     double  axis_w;
  39.     double  axis_h;
  40.     double  title_w;
  41.     double  title_h;
  42.     FILE   *plotterFile;
  43.     int     clipminX;
  44.     int     clipminY;
  45.     int     clipmaxX;
  46.     int     clipmaxY;
  47. }       mydata;
  48. /*ARGSUSED*/
  49. int
  50. hpglInit(stream, width, height, title_family, title_size,
  51.  axis_family, axis_size, flags, outInfo, errmsg)
  52. FILE   *stream; /* output stream */
  53. int     width; /* desired width of space in microns */
  54. int     height; /* desired height in microns */
  55. char   *title_family; /* name of font for titles */
  56. double  title_size; /* size of font for titles */
  57. char   *axis_family; /* name of font for axes */
  58. double  axis_size; /* size of font for axes */
  59. int     flags; /* predicate values (ignored) */
  60. xgOut  *outInfo; /* my structure */
  61. char    errmsg[ERRBUFSIZE]; /* a place to complain to */
  62. {
  63.     mydata *myInfo;
  64.     myInfo = (mydata *) Malloc(sizeof(mydata));
  65.     if (myInfo == NULL)
  66. return 0;
  67.     *outInfo = hpglInfo;
  68.     outInfo->area_w = MIN(MAXX, width / 25);
  69.     outInfo->area_h = MIN(MAXY, height / 25);
  70.     /* magic formulas:  input sizes are in points = 1/72 inch */
  71.     /* my sizes are in cm */
  72.     /* plotter units are in units of .025mm ~= 1/1016 inch */
  73.     /*
  74.      * have to warn of height 1.5 times larger or get bitten by plotter's
  75.      * internal padding
  76.      */
  77.     /* widths are (arbitrarily) selected to be 2/3 of the height */
  78.     /* (cancels with width factor) */
  79.     myInfo->axis_w = axis_size * .666 * 2.54 / 72.;
  80.     myInfo->axis_h = axis_size * 2.54 / 72.;
  81.     myInfo->title_w = title_size * .666 * 2.54 / 72.;
  82.     myInfo->title_h = title_size * 2.54 / 72.;
  83.     outInfo->axis_pad = axis_size * 1016. * 1.5 / 72.;
  84.     outInfo->axis_width = axis_size * 1016. * 1.5 / 72.;
  85.     outInfo->axis_height = axis_size * 1016. * .666 / 72.;
  86.     outInfo->title_width = title_size * 1016. * 1.5 / 72.;
  87.     outInfo->title_height = title_size * 1016. * .666 / 72.;
  88.     outInfo->user_state = (char *) myInfo;
  89.     myInfo->plotterFile = stream;
  90.     myInfo->clipminX = 0;
  91.     myInfo->clipminY = 0;
  92.     myInfo->clipmaxX = MAXX;
  93.     myInfo->clipmaxY = MAXY;
  94.     fprintf(myInfo->plotterFile, "PG;IN;n");
  95.     fprintf(myInfo->plotterFile, "DI1,0;n");
  96.     fprintf(myInfo->plotterFile, "IW%d,%d,%d,%d;n", MAPX(myInfo, 0),
  97.     MAPY(myInfo, myInfo->clipmaxY - myInfo->clipminY),
  98.     MAPX(myInfo, myInfo->clipmaxX - myInfo->clipminX),
  99.     MAPY(myInfo, 0));
  100.     return (1);
  101. }
  102. static void
  103. hpglText(userState, x, y, text, just, style)
  104. mydata *userState; /* my state information  */
  105. int     x,
  106.         y; /* coords of text origin */
  107. char   *text; /* what to put there */
  108. int     just; /* how to justify */
  109.  /*
  110.   * where the origin is relative to where the text should go as a function of
  111.   * the various values of just
  112.   * 
  113.   * T_UPPERLEFT     T_TOP       T_UPPERRIGHT T_LEFT          T_CENTER    T_RIGHT
  114.   * T_LOWERLEFT     T_BOTTOM    T_LOWERRIGHT
  115.   * 
  116.   */
  117. int     style; /* T_AXIS = axis font, T_TITLE = title font */
  118. {
  119.     fprintf(userState->plotterFile, "PU;SP%d;", TEXTCOLOR);
  120.     fprintf(userState->plotterFile, "PA%d,%d;", MAPX(userState, x), MAPY(userState, y));
  121.     switch (style) {
  122.     case T_AXIS:
  123. fprintf(userState->plotterFile, "SI%f,%f;", userState->axis_w, userState->axis_h);
  124. break;
  125.     case T_TITLE:
  126. fprintf(userState->plotterFile, "SI%f,%f;", userState->title_w, userState->title_h);
  127. break;
  128.     default:
  129. printf("bad text style %d in hpglTextn", style);
  130. exit(1);
  131. break;
  132.     }
  133.     switch (just) {
  134.     case T_UPPERLEFT:
  135. fprintf(userState->plotterFile, "LO3;n");
  136. break;
  137.     case T_TOP:
  138. fprintf(userState->plotterFile, "LO6;n");
  139. break;
  140.     case T_UPPERRIGHT:
  141. fprintf(userState->plotterFile, "LO9;n");
  142. break;
  143.     case T_LEFT:
  144. fprintf(userState->plotterFile, "LO2;n");
  145. break;
  146.     case T_CENTER:
  147. fprintf(userState->plotterFile, "LO5;n");
  148. break;
  149.     case T_RIGHT:
  150. fprintf(userState->plotterFile, "LO8;n");
  151. break;
  152.     case T_LOWERLEFT:
  153. fprintf(userState->plotterFile, "LO1;n");
  154. break;
  155.     case T_BOTTOM:
  156. fprintf(userState->plotterFile, "LO4;n");
  157. break;
  158.     case T_LOWERRIGHT:
  159. fprintf(userState->plotterFile, "LO7;n");
  160. break;
  161.     default:
  162. printf("bad justification type %d in hpglTextn", just);
  163. exit(1);
  164. break;
  165.     }
  166.     fprintf(userState->plotterFile, "LB%s3;", text);
  167. }
  168. static int penselect[8] =
  169. {PEN1, PEN2, PEN3, PEN4, PEN5, PEN6, PEN7, PEN8};
  170. static int lineselect[8] =
  171. {LINE1, LINE2, LINE3, LINE4, LINE5, LINE6,
  172.  LINE7, LINE8};
  173. static void
  174. hpglSeg(userState, ns, segs, width, style, lappr, color)
  175. mydata *userState; /* my state information (not used) */
  176. int     ns; /* number of segments */
  177. XSegment *segs; /* X array of segments */
  178. int     width; /* width of lines in pixels */
  179. int     style; /* L_VAR = dotted, L_AXIS = grid, L_ZERO = axis */
  180. int     lappr; /* line style */
  181. int     color; /* line color */
  182. {
  183.     int     i;
  184.     if (style == L_ZERO) {
  185. fprintf(userState->plotterFile, "SP%d;", PENAXIS); /* select correct pen */
  186. fprintf(userState->plotterFile, "LT;"); /* solid line style */
  187.     }
  188.     else if (style == L_AXIS) {
  189. fprintf(userState->plotterFile, "SP%d;", PENGRID); /* select correct pen */
  190. fprintf(userState->plotterFile, "LT;"); /* solid line style */
  191.     }
  192.     else if (style == L_VAR) {
  193. if ((color < 0) || (color > 7)) {
  194.     printf("out of range line color %d in hpglLinen", color);
  195.     exit(1);
  196. }
  197. fprintf(userState->plotterFile, "SP%d;", penselect[color]); /* select correct pen */
  198. if ((lappr < 0) || (lappr > 7)) {
  199.     printf("out of range line style %d in hpglLinen", lappr);
  200.     exit(1);
  201. }
  202. if (lappr == 0) {
  203.     fprintf(userState->plotterFile, "LT;"); /* select solid line
  204.  * type */
  205. }
  206. else {
  207.     fprintf(userState->plotterFile, "LT%d;", lineselect[lappr]); /* select line type */
  208. }
  209.     }
  210.     else {
  211. printf("unknown style %d in hpglLinen", style);
  212. exit(1);
  213.     }
  214.     for (i = 0; i < ns; i++) {
  215. if (!i || ((segs[i].x1 != segs[i - 1].x2) || (segs[i].y1 != segs[i - 1].y2))) {
  216.     /* MOVE */
  217.     fprintf(userState->plotterFile, "PU;PA%d,%d;n", MAPX(userState, segs[i].x1),
  218.     MAPY(userState, segs[i].y1));
  219. }
  220. /* DRAW */
  221. if (width <= 1) {
  222.     fprintf(userState->plotterFile, "PD;PA%d,%d;n", MAPX(userState, segs[i].x2),
  223.     MAPY(userState, segs[i].y2));
  224. }
  225. else { /* ugly - wide lines -> rectangles */
  226.     double  frac;
  227.     int     lx,
  228.             ly;
  229.     int     urx,
  230.             ury,
  231.             ulx,
  232.             uly,
  233.             llx,
  234.             lly,
  235.             lrx,
  236.             lry;
  237.     frac = (width / 2) / sqrt((double)
  238.       ((segs[i].x1 - segs[i].x2) *
  239.        (segs[i].x1 - segs[i].x2)) +
  240.       ((segs[i].y1 - segs[i].y2) *
  241.        (segs[i].y1 - segs[i].y2)));
  242.     lx = frac * (segs[i].y2 - segs[i].y1);
  243.     ly = -frac * (segs[i].x2 - segs[i].x1);
  244.     urx = segs[i].x2 + lx;
  245.     ury = segs[i].y2 + ly;
  246.     ulx = segs[i].x2 - lx;
  247.     uly = segs[i].y2 - ly;
  248.     llx = segs[i].x1 - lx;
  249.     lly = segs[i].y1 - ly;
  250.     lrx = segs[i].x1 + lx;
  251.     lry = segs[i].y1 + ly;
  252.     fprintf(userState->plotterFile, "PU;PA%d,%d;", MAPX(userState, llx),
  253.     MAPY(userState, lly));
  254.     fprintf(userState->plotterFile, "PM0;");
  255.     fprintf(userState->plotterFile, "PD,PA%d,%D;PA%d,%D;PA%d,%d;n",
  256.     MAPX(userState, lrx), MAPY(userState, lry),
  257.     MAPX(userState, urx), MAPY(userState, ury),
  258.     MAPX(userState, ulx), MAPY(userState, uly));
  259.     fprintf(userState->plotterFile, "PM2;FP;EP;");
  260. }
  261.     }
  262.     fprintf(userState->plotterFile, "PU;");
  263. }
  264. static char *markselect[8] =
  265. {MARK1, MARK2, MARK3, MARK4, MARK5, MARK6,
  266.  MARK7, MARK8};
  267. static void
  268. hpglDot(userState, x, y, style, type, color)
  269. mydata *userState; /* my state information (not used) */
  270. int     x,
  271.         y; /* coord of dot */
  272. int     style; /* type of dot */
  273. int     type; /* dot style variation */
  274. int     color; /* color of dot */
  275. {
  276.     /* move to given coord */
  277.     fprintf(userState->plotterFile, "PU;PA%d,%d;n", MAPX(userState, x), MAPY(userState, y));
  278.     if ((color < 0) || (color > 7)) {
  279. printf("unknown color %d in hpglDotn", color);
  280. exit(1);
  281.     }
  282.     fprintf(userState->plotterFile, "SP%d;", penselect[color]);
  283.     if (style == P_PIXEL) {
  284. fprintf(userState->plotterFile, "PD;PU;n");
  285.     }
  286.     else if (style == P_DOT) {
  287. fprintf(userState->plotterFile, "LT;PM0;CI40;PM2;FT;EP;n");
  288.     }
  289.     else if (style == P_MARK) {
  290. if ((type < 0) || (type > 7)) {
  291.     printf("unknown marker type %d in hpglDotn", type);
  292.     exit(1);
  293. }
  294. /*
  295.  * fprintf(userState->plotterFile,"LT;CA5;LO4;SI0.1;LB%s3;n",marksele
  296.  * ct[type]);
  297.  */
  298. fprintf(userState->plotterFile, "LT;CS5;LO4;SI0.15;SM%s;PR0,0;SM;CS;n", markselect[type]);
  299.     }
  300.     else {
  301. printf("unknown marker style %d in hpglDotn", style);
  302. exit(1);
  303.     }
  304. }
  305. static void
  306. hpglEnd(userState)
  307. mydata *userState; /* my state information (not used) */
  308. {
  309.     fprintf(userState->plotterFile, "SP;PG;IN;n");
  310.     fflush(userState->plotterFile);
  311.     return;
  312. }