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

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Tgif Output
  3.  *
  4.  * Christos Zoulas
  5.  */
  6. #include <stdio.h>
  7. #include <X11/Xlib.h>
  8. #include "hard_devices.h"
  9. #include "xgout.h"
  10. #define COLOR "DarkSlateGray"
  11. typedef struct {
  12.     char   *title_font;
  13.     char   *axis_font;
  14.     int     title_size;
  15.     int     axis_size;
  16.     FILE   *strm;
  17. }       Info;
  18. char   *tgif_prologue[] =
  19. {
  20.     "state(0,13,0,0,0,16,1,5,1,1,0,0,1,0,1,0,1,0,4,0,0,0,10,0).n",
  21.     "%n",
  22.     "% Tgif xgraph output.n",
  23.     "%n",
  24.     0
  25. };
  26. /*
  27.  * Hardcopy Interface for Xgraph
  28.  *
  29.  * Major differences from first version:
  30.  *   Four new parameters are passed to the device initialization routine:
  31.  *   title_family, title_size, axis_family, and axis_size.  See the
  32.  *   description of xg_init() for details.
  33.  *
  34.  *   Clipping is done automatically by xgraph.  The xg_clip() routine
  35.  *   is obsolete.
  36.  *
  37.  *   The xg_line() routine has become the xg_seg() routine.  It now
  38.  *   draws segments rather than a series of lines.
  39.  *
  40.  *   A new field (max_segs) in the device structure now specifies
  41.  *   the maximum number of segments the device can handle in a group.
  42.  */
  43. void    tgifText();
  44. void    tgifDot();
  45. void    tgifSeg();
  46. void    tgifEnd();
  47. int 
  48. tgifInit(strm, width, height, title_family, title_size,
  49.   axis_family, axis_size, flags, out_info, errmsg)
  50. FILE   *strm; /* Output stream              */
  51. int     width,
  52.         height; /* Size of space (microns)    */
  53. char   *title_family; /* Name of title font family  */
  54. double  title_size; /* Title font height (points) */
  55. char   *axis_family; /* Name of axis font family   */
  56. double  axis_size; /* Axis font height (points)  */
  57. int     flags; /* Flags                      */
  58. xgOut  *out_info; /* Device info (RETURN)       */
  59. char    errmsg[ERRBUFSIZE]; /* Error message area         */
  60. {
  61.     Info   *tgif_info;
  62.     char  **l;
  63.     double  scx,
  64.             scy;
  65.     tgif_info = (Info *) Malloc(sizeof(*tgif_info));
  66.     for (l = tgif_prologue; *l; l++)
  67. fprintf(strm, "%sn", *l);
  68.     out_info->dev_flags = 0;
  69.     scx = width /  512.0;
  70.     scy = height / 512.0;
  71.     if (scx > scy) {
  72. scy /= scx;
  73. scx = 1;
  74.     }
  75.     else {
  76. scx /= scy;
  77. scy = 1;
  78.     }
  79.     out_info->bdr_pad = title_size / 4;
  80.     out_info->axis_pad = 2.0 * axis_size;
  81.     out_info->legend_pad = 0;
  82.     out_info->area_w = width * 0.00283 * scx; /* pts per micron */
  83.     out_info->area_h = height * 0.00283 * scy;
  84.     out_info->tick_len = axis_size;
  85.     out_info->axis_height = axis_size;
  86.     out_info->title_height = title_size;
  87.     out_info->axis_width = (axis_size * 5.0) / 12.0;
  88.     out_info->title_width = (title_size * 5.0) / 12.0;
  89.     out_info->max_segs = 100;
  90.     out_info->xg_text = tgifText;
  91.     out_info->xg_seg = tgifSeg;
  92.     out_info->xg_dot = tgifDot;
  93.     out_info->xg_end = tgifEnd;
  94.     out_info->user_state = (char *) tgif_info;
  95.     tgif_info->title_font = title_family;
  96.     tgif_info->axis_font = axis_family;
  97.     tgif_info->title_size = title_size;
  98.     tgif_info->axis_size = axis_size;
  99.     tgif_info->strm = strm;
  100.     return 1;
  101. }
  102. /* Text justifications */
  103. #define T_CENTER 0
  104. #define T_LEFT 1
  105. #define T_UPPERLEFT 2
  106. #define T_TOP 3
  107. #define T_UPPERRIGHT 4
  108. #define T_RIGHT 5
  109. #define T_LOWERRIGHT 6
  110. #define T_BOTTOM 7
  111. #define T_LOWERLEFT 8
  112. /* Text styles */
  113. #define T_AXIS 0
  114. #define T_TITLE 1
  115. static void 
  116. tgif_just(x, y, just, size, len)
  117. int    *x,
  118.        *y; /* Given location (lower left) */
  119. int     just; /* Justification */
  120. int     size; /* Size in points */
  121. int     len; /* Number of chars */
  122. /*
  123.  * Unfortunately, tgif really can't display text with a justification.
  124.  * This is a horrible hack to try to get around the problem.  It tries
  125.  * to compute a rough bounding box for the text based on the text height
  126.  * and the string length and offset `x,y' appropriately for the justification.
  127.  * This is only a hack...
  128.  */
  129. {
  130.     int     t_width,
  131.             t_height;
  132.     t_height = size;
  133.     t_width = (size * len * 5) / 12; /* Horrible estimate */
  134.     switch (just) {
  135.     case T_CENTER:
  136. *x -= t_width / 2;
  137. *y -= t_height / 2;
  138. break;
  139.     case T_LEFT:
  140. *y -= t_height / 2;
  141. break;
  142.     case T_UPPERLEFT:
  143. /* nothing */
  144. break;
  145.     case T_TOP:
  146. *x -= t_width / 2;
  147. break;
  148.     case T_UPPERRIGHT:
  149. *x -= t_width;
  150. break;
  151.     case T_RIGHT:
  152. *x -= t_width;
  153. *y -= t_height / 2;
  154. break;
  155.     case T_LOWERRIGHT:
  156. *x -= t_width;
  157. *y -= t_height;
  158. break;
  159.     case T_BOTTOM:
  160. *x -= t_width / 2;
  161. *y -= t_height;
  162. break;
  163.     case T_LOWERLEFT:
  164. *y -= t_height;
  165. break;
  166.     }
  167.     /*
  168.      * Also, tgif seems to put a space above all text it draws. The
  169.      * computation below compensates for this.
  170.      */
  171.     *y += (size / 3);
  172. }
  173. void 
  174. tgifText(user_state, x, y, text, just, style)
  175. char   *user_state; /* Value set in xg_init   */
  176. int     x,
  177.         y; /* Text position (pixels) */
  178. char   *text; /* Null terminated text   */
  179. int     just; /* Justification (above)  */
  180. int     style; /* Text style (above)     */
  181. /*
  182.  * This routine should draw text at the indicated position using
  183.  * the indicated justification and style.  The justification refers
  184.  * to the location of the point in reference to the text.  For example,
  185.  * if just is T_LOWERLEFT,  (x,y) should be located at the lower left
  186.  * edge of the text string.
  187.  */
  188. {
  189.     char   *font;
  190.     int     size;
  191.     Info   *tgif = (Info *) user_state;
  192.     /*
  193.      * Obj = text(_Color,_X,_Y,_Font,_TextStyle,_TextSize,_NumLines,_TextJust,
  194.      *   _TextRotate,_PenPat,_BBoxW,_BBoxH,_Id,_TextDPI,_Asc,_Des,
  195.      *   _ObjFill,_Vspace,StrList),
  196.      */
  197.     /* font ok too */
  198.     style == T_AXIS ? tgif->axis_font :
  199. tgif->title_font;
  200.     /* ok 0, 1 as in tgif */
  201.     size = style == T_AXIS ? tgif->axis_size :
  202. tgif->title_size;
  203.     tgif_just(&x, &y, just, size, strlen(text));
  204.     if (size <= 8)
  205. size = 0;
  206.     else if (size <= 10)
  207. size = 1;
  208.     else if (size <= 12)
  209. size = 2;
  210.     else if (size <= 14)
  211. size = 3;
  212.     else if (size <= 18)
  213. size = 4;
  214.     else
  215. size = 5;
  216.     fprintf(tgif->strm, 
  217. "text('%s',%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,[nt",
  218.     COLOR, x, y, 0, style, size, 1, 0, 0, 1, 0, 0, 0, 0, 18, 4, 0, 0);
  219.     fprintf(tgif->strm,
  220.     ""%s"]).n", text);
  221. }
  222. /* Line Styles */
  223. #define L_AXIS 0
  224. #define L_ZERO 1
  225. #define L_VAR 2
  226. void 
  227. tgifSeg(user_state, ns, seglist, width, style, lappr, color)
  228. char   *user_state; /* Value set in xg_init */
  229. int     ns; /* Number of segments   */
  230. XSegment *seglist; /* X array of segments  */
  231. int     width; /* Width of lines       */
  232. int     style; /* See above            */
  233. int     lappr; /* Line appearence      */
  234. int     color; /* Line color (if any)  */
  235. {
  236.     Info   *tgif = (Info *) user_state;
  237.     int     i,
  238.             j,
  239.             k;
  240.     /*
  241.      * poly(_Color,_NumVs,_Vs,_LineStyle,_LineWidth,_PenPat,_Id,_Spline,
  242.      * _ObjFill,_Dash,AttrList),
  243.      */
  244.     static int style_list[] =
  245.     {
  246. 1, 10, 7, 6, 5, 4, 3, 2
  247.     };
  248.     for (i = 0; i < ns; i++) {
  249. fprintf(tgif->strm, "poly('%s',2,[%d,%d,%d,%d],", COLOR, 
  250. seglist[i].x1, seglist[i].y1,
  251. seglist[i].x2, seglist[i].y2);
  252. fprintf(tgif->strm, "%d,%d,%d,%d,%d,%d,%d,[n]).n", 0, width, 
  253. style_list[lappr], 0, 0, style_list[lappr], 0);
  254.     }
  255. }
  256. /* Marker styles */
  257. #define P_PIXEL 0
  258. #define P_DOT 1
  259. #define P_MARK 2
  260. void 
  261. tgifDot(user_state, x, y, style, type, color)
  262. char   *user_state; /* Value set in xg_init    */
  263. int     x,
  264.         y; /* Location in pixel units */
  265. int     style; /* Dot style               */
  266. int     type; /* Type of marker          */
  267. int     color; /* Marker color (if any)   */
  268. /*
  269.  * This routine should draw a marker at location `x,y'.  If the
  270.  * style is P_PIXEL,  the dot should be a single pixel.  If
  271.  * the style is P_DOT,  the dot should be a reasonably large
  272.  * dot.  If the style is P_MARK,  it should be a distinguished
  273.  * mark which is specified by `type' (0-7).  If the output
  274.  * device is capable of color,  the marker should be drawn in
  275.  * `color' (0-7) which corresponds with the color for xg_line.
  276.  */
  277. {
  278. }
  279. void 
  280. tgifEnd(user_state)
  281. char   *user_state;
  282. /*
  283.  * This routine is called after a drawing sequence is complete.
  284.  * It can be used to clean up the user state and set the device
  285.  * state appropriately.  This routine is optional in the structure.
  286.  */
  287. {
  288.     Info   *tgif = (Info *) user_state;
  289.     fclose(tgif->strm);
  290. }