home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / d / dots151.zip / GRAPHSRC.ZIP / GPS.C < prev    next >
C/C++ Source or Header  |  1990-07-15  |  22KB  |  687 lines

  1. /*
  2.     gps -    graphics interface routine for PostScript printers
  3.  
  4.     history...
  5.         5 Jul 90    Version 1.45: Only closing output file once.  Default
  6.                     output filename is foo.ps, where foo is the root name 
  7.                     of the first data file.
  8.         4 Jul 90    Version 1.44: Getting parameters from configuration
  9.                     file.
  10.         23 Jun 90    Version 1.42: Ported to Turbo C.
  11.         19 Jun 90    Version 1.41: Adding strokes if needed within a long 
  12.                     series of lineto commands.  
  13.         28 Nov 89    Version 1.40: generating structure comments for
  14.                     Nelson Beebe's DVIALW (.DVI -> Apple LaserWriter).
  15.         1 Nov 89    Version 1.35: widened characters by 20% for better
  16.                     superscript placement.  Something is still wrong,
  17.                     especially with the last label on the X axis.
  18.         26 May 89    Version 1.34: minor format changes in prologue and
  19.                     clear_graph.
  20.         12 May 89    Version 1.33: Using "show" for all text rather than
  21.                     "s", so these labels don't have opaque backgrounds. 
  22.                     POSTOGRF adds its own definition of "s", including
  23.                     routines for adding opaque backgrounds.
  24.         4 May 89    Version 1.32: Putting whitespace after "]" everywhere.
  25.                     Writing version
  26.                      number into output file.  Margin
  27.                     specification revised so that portrait or landscape
  28.                     orientation requests aren't dropped.
  29.         2 May 89    Version 1.31: Adding a stroke before each label.
  30.         25 Apr 89    Version 1.3: Using PostScript "translate" command to
  31.                     adjust margins rather than adding a constant
  32.                     displacement to every position.  Printing size of
  33.                     plot area.  Default margins and sizes now match the
  34.                     MITRE document mat standards.
  35.         21 Apr 89    Version 1.2: shorter prologue, implementing grayscale
  36.         14 Apr 89    Version 1.12: Adding "st" commands periodically,
  37.                     to avoid overrunning printer's stack.
  38.         28 Sep 88    Version 1.11: L or P at end of either dimension
  39.                     input line specifies landscape or portrait orientation.
  40.         19 Jul 88    Version 1.10: Deleting output file before opening it.
  41.         9 May 88    Adapted from LIPS-10 driver
  42.         9 Jul 87    Creating output file if it doesn't already exist
  43.         21 May 87    Stronger warning msg about using default output port
  44.         13 May 87    Default margins, width, and height set for landscape
  45.                     orientation.
  46.         1 May 87    Adapted from Hewlett Packard plotter routine
  47.         23 Jun 86    Adapted from Houstin Instruments plotter routine
  48.         27 Oct 87    Environment variable "plot_setup" can contain an
  49.                     alternate setup string.
  50.  
  51.     bugs...
  52.  
  53. bench needs to check for "erasing"
  54. g3x needs to call set_height to set character size.
  55.  
  56. */
  57.  
  58. #include <stdio.h>
  59. #include <math.h>
  60. #include <stdlib.h>
  61. #include <string.h>
  62. #include <ctype.h>
  63. #include "g.h"
  64. #include "config.h"
  65.  
  66. #define VERSION "1.45"
  67. #include "gps.h"    /* this defines "prelude", the introductory text */
  68.  
  69. #define TI(x,y) /* printf("%15d = %s\n", x, y)      /**/
  70. #define TR(x,y) /* printf("%15.4g = %s\n", x, y)    /**/
  71.  
  72. #define UNIT (1./300.)
  73. #define BUFSIZE 80
  74. #define DEFAULT_FILE "COM1"
  75.  
  76.                 /* default margins, defined assuming portrait orientation */
  77. #define LMARGIN 1.125
  78. #define RMARGIN 1.125
  79. #define TMARGIN 1.5
  80. #define BMARGIN 1.5
  81.  
  82. /*    imported variables    */
  83.  
  84. extern char *default_script_file;
  85.  
  86. /*    exported graphics variables    */
  87.  
  88. char *machine        =    "PostScript";
  89. char *interface_version    =    VERSION;
  90. static char default_config_file[] = "GRAPHPS.CFG";
  91. char *config_file    =    NULL;
  92. int plotting_device    =    1;
  93. int erasing            =    0;
  94.  
  95. int max_color        =    1;
  96.  
  97. int current_color    =    0;
  98. double current_intensity = 1.;
  99.  
  100.                 /* these dimensions assume landscape orientation */
  101. int pixels_wide        =    300*11;        /* width of screen in pixels */
  102. int pixels_high        =    30*85;        /* height of screen in pixels */
  103. double best_width    =    1.;            /* relative height/width for landscape */
  104. double best_height    =    .720;
  105. int pen_diameter    =    3;
  106.  
  107. int char_rows        =    30*85/65;    /* text parameters */
  108. int    char_columns    =    300*11/30;    /* (recalculated by init_graphics) */
  109. int    char_height        =    65;
  110. int    char_width        =    30;
  111. int    x_offset        =    0;
  112. int    y_offset        =    0;
  113. int    char_v_adjusted    =    1;
  114. int    char_h_adjusted    =    1;
  115.  
  116. int has_cursor_keys    =    0;            /* no cursor keys, 
  117.                                         so the rest of these are ignored... */
  118. int    up_arrow        =    0x48;        /* cursor key codes */
  119. int    down_arrow        =    0x50;
  120. int    left_arrow        =    0x4b;
  121. int    right_arrow        =    0x4d;
  122. int    escaped_arrows    =    1;            /* cursor keys are preceded by 0 */
  123. int    escape_char        =    0;
  124.  
  125. /* an 'A' on row r, column c  has lower left corner on raster 
  126.                 r*char_height + y_offset 
  127.     at pixel
  128.                 c*char_width + x_offset            */
  129.  
  130.  
  131. struct PRIM_ATTR prim_attr=
  132.     {2,     /* # colors                          */
  133.     16,     /* # intensities                     */
  134.     0,      /* nonzero if supported in hardware  */
  135.     9,      /* # linestyles in hardware          */
  136.     1,      /* # linestyles in software          */
  137.     1,      /* # linewidths                      */
  138.     0,      /* nonzero if supported in hardware  */
  139.     1,      /* minimum linewidth                 */
  140.     14,     /* maximum linewidth (.2 in)         */
  141.     1,      /* # pens in hardware                */
  142.     0,      /* # pens in software                */
  143.     1,      /* # fonts                           */
  144.     1,      /* # character sizes                 */
  145.     0,      /* nonzero if supported in hardware  */
  146.     10,     /* minimum character height (pixels) */
  147.     10,     /* maximum character height (pixels) */
  148.     0,      /* # markers in hardware             */
  149.     0,      /* # markers in software             */
  150.     0       /* # pick IDs in hardware            */
  151.     };
  152.  
  153.  
  154. static draw();
  155. static erase();
  156. static text();
  157. static character();
  158.  
  159. static font=0;
  160. static int plotter_type;
  161. FILE *plot_file=stdout;
  162. static int style_code=1;
  163. static int color_code=0;
  164. static current_width=3;
  165. static cx=0, cy=0;    /*    actual position of pen  */
  166. static something_printed=0;    /* nonzero if something printed since last
  167.                                 PAGE command (graphics_clear())  */
  168. #define WAIT something_printed=1
  169. #define DASHES 8
  170. #define MAX_STYLE 9
  171. char styles[DASHES*MAX_STYLE]={    /* 0 - solid */
  172.     8,2,0,0,0,0,0,0,            /* 1 - dashed */
  173.     3,2,0,0,0,0,0,0,            /* 2 - short dashes */ 
  174.     1,3,0,0,0,0,0,0,            /* 3 - dotted */ 
  175.     16,2,1,2,0,0,0,0,            /* 4 - dash-dot */ 
  176.     16,2,1,2,1,2,0,0,            /* 5 - dash-dot-dot */ 
  177.     16,2,1,2,1,2,1,2,             /* 6 - dash-dot-dot-dot */
  178.     16,2,16,2,1,2,0,0,             /* 7 - dash-dash-dot */
  179.     16,2,16,2,1,2,1,2,             /* 8 - dash-dash-dot-dot */
  180.     15,10,0,0,0,0,0,0};            /* 9 - long dashes */
  181.  
  182. static set_style(style) int style;
  183. {    char *t;
  184.     int i;
  185.  
  186.     if(style<=0) 
  187.         {style=0;
  188.         if(style_code==style) return;
  189.         WAIT;
  190.  
  191.         fprintf(plot_file,"cpt st m\n[] 0 sd  %% solid line\n");
  192.         }
  193.     else
  194.         {if(style>=prim_attr.hardware_linestyles)
  195.             style=prim_attr.hardware_linestyles-1;
  196.         if(style_code==style) return;
  197.         WAIT;
  198.         t=styles+DASHES*(style-1);
  199.         fprintf(plot_file, "cpt st m\n[");
  200.         for (i=0; i<DASHES && *t; i++) 
  201.             fprintf(plot_file, "%1.0f ", 15.* (current_width/3-1+ *t++ ));
  202.         fprintf(plot_file, "] 0 sd\n");
  203.         }
  204.     style_code=style;
  205. }
  206.  
  207. static set_width(width) int width; 
  208. {    width *= 3;
  209.     if(width<3) width=3;
  210.     else if(width>64) width=64;
  211.     if(width==current_width) return;
  212.     fprintf(plot_file,"cpt st m\n%d setlinewidth\n",(width*10)/3);
  213.     current_width=width;
  214. }
  215.  
  216. /*    set_color - set color to be used for subsequent primitives  */
  217. set_color(color) int color; {}
  218. inquire_color() {return 1;}
  219.  
  220. /*
  221.     set_intensity - set intensity to be used for subsequent primitives
  222.     1 -> black   (easiest to see)
  223.     0 -> white   (most subtle)
  224. */
  225. set_intensity(intensity) double intensity;
  226. {    if(intensity < 0.) intensity = 0.;
  227.     else if(intensity > 1.) intensity = 1.;
  228.     if(current_intensity == intensity) return;
  229.     current_intensity = intensity;
  230.     fprintf(plot_file,"cpt st m %3.3f sg\n", 1. - current_intensity);
  231. }
  232. double inquire_intensity() {return current_intensity;}
  233.  
  234.  
  235. /*    draw - draw a straight line     */
  236.  
  237. static int draw(x1, y1, x2, y2) int x1, y1, x2, y2;
  238. {    int t, d1, d2;
  239.     static int segments=0;
  240.  
  241.     y1= pixels_high-1-y1; y2= pixels_high-1-y2; 
  242.     d1=maximum(abs(cx-x1), abs(cy-y1));
  243.     d2=maximum(abs(cx-x2), abs(cy-y2));
  244. #ifdef DEBUG
  245.     printf("\nat (%d,%d)  drawing (%d,%d)(%d away) to (%d,%d)(%d away)",
  246.                                              cx, cy, x1, y1, d1, x2, y2, d2);
  247. #endif
  248.     if(d2<d1)
  249.         {t=x1; x1=x2; x2=t; t=y1; y1=y2; y2=t; t=d1; d1=d2; d2=t;
  250. #ifdef DEBUG
  251.         puts("swapping");
  252. #endif
  253.         }
  254. #ifdef DEBUG
  255.     putchar('\n');
  256. #endif
  257.     WAIT;
  258.     segments++;
  259.     if(d1)
  260.         {
  261.         if(segments > 100) 
  262.             {        /* 
  263.                         "stroke" to clear printer memory of 
  264.                         accumulated "lineto" and "moveto" commands
  265.                     */
  266.             fprintf(plot_file, "st \n");
  267.             segments = 0;
  268.             }
  269.         fprintf(plot_file,"%ld %ld m \n",(x1*10L)/3L,(y1*10L)/3L);
  270.         }
  271.     else
  272.         {if(segments > 100) 
  273.             {        /* 
  274.                         "stroke" to clear printer memory of 
  275.                         accumulated "lineto" and "moveto" commands
  276.                     */
  277.             fprintf(plot_file, "cpt st m\n");
  278.             segments = 0;
  279.             }
  280.         }
  281.     fprintf(plot_file,"%ld %ld l \n",(x2*10L)/3L,(y2*10L)/3L);
  282.     cx=x2; cy=y2;
  283. }
  284.  
  285. /*    gotoxy - move pen to new position (used before text display) */
  286.  
  287. gotoxy(x,y) int x,y;
  288. {    y= pixels_high-1-y; 
  289.     if (x<0) x=0; else if (x>=pixels_wide) x=pixels_wide-1;
  290.     if (y<0) y=0; else if (y>=pixels_high) y=pixels_high-1;
  291.     if(x==cx && y==cy) return;
  292.     WAIT;
  293.     fprintf(plot_file,"%ld %ld m \n",(x*10L)/3L,(y*10L)/3L);
  294.     cx=x; cy=y;
  295. }
  296.  
  297. static nil() {}
  298.  
  299. /* exported function pointers */
  300. int (*draw_line)()    =    draw;
  301. int (*erase_line)()    =    nil;
  302. int (*draw_text)()    =    text;
  303. int (*draw_char)()    =    character;
  304.  
  305. /*    find a character in a string (case insensitive) */
  306. static int strichr(s, c) char *s, c;
  307. {
  308.     for (c=tolower(c); *s; s++)
  309.         if(tolower(*s) == c)
  310.             return 1;
  311.     return 0;
  312. }
  313.  
  314. /*        init - initialize the graphics system    */
  315. init_graphics()
  316. {    int d1, d2, c, i, vel;
  317.     double left, top, right, bottom, w, h, hmax, wmax;
  318.     char buf[BUFSIZE], inbuf[BUFSIZE], *s, *t, **sp;
  319.  
  320.     static int offset_ask = 1,
  321.         size_ask = 1,
  322.         orientation_ask = 1,
  323. /*        plotter_ask = 1, */
  324. /*        velocity_ask = 1, */
  325.         file_ask = 0;
  326.     static double offset[2] = {BMARGIN, LMARGIN};
  327.     static double size[2] = {11. - BMARGIN - TMARGIN, 8.5 - LMARGIN - RMARGIN};
  328.     static int portrait = 0, landscape = 0;
  329.     static char *port_name = NULL;
  330.  
  331.  
  332.     static PARAM parmv[] = {
  333.                 {'o', REAL, &offset_ask, offset, 2},
  334.                 {'l', REAL, &offset_ask, &offset[0]},
  335.                 {'t', REAL, &offset_ask, &offset[1]},
  336.                 {'s', REAL, &size_ask, size, 2},
  337.                 {'w', REAL, &size_ask, &size[0]},
  338.                 {'h', REAL, &size_ask, &size[1]},
  339.                 {'p', BOOLEAN, &orientation_ask, &portrait, 0},
  340.                 {'l', BOOLEAN, &orientation_ask, &landscape, 0},
  341.                 {'f', STRING, &file_ask, &port_name, 1},
  342.                 {'\0'}};
  343.  
  344.     if(config_file == NULL) config_file = default_config_file;
  345.     config(config_file, NULL, parmv, buf, BUFSIZE);
  346.  
  347.     if(port_name == NULL && version() >= 0x200)
  348.         port_name = getenv("PLOT_PORT");
  349.     if(port_name == NULL) 
  350.         {port_name = strncpy(buf, default_script_file, BUFSIZE-4);
  351.         s = strchr(port_name, '.');
  352.         if(s != NULL) *s = 0;
  353.         strcat(port_name, ".ps");
  354.         }
  355.     else file_ask = 0;
  356.     if(file_ask)
  357.         {port_name = strncpy(buf, port_name, BUFSIZE);
  358.         printf("Enter output file (default %s): ",buf);
  359.         gets(inbuf);
  360.         if(inbuf[0]) strcpy(buf,inbuf);
  361.         }
  362.     else
  363.         printf("\noutput written to %s\n", port_name);
  364.  
  365.     unlink(port_name);                /* delete the file if it exists */
  366.     plot_file=fopen(port_name, "w");    /* this will open a file or device */
  367.     if(plot_file==NULL) {printf("can\'t open output file %s", port_name); exit(1);}
  368.  
  369.     buf[0]=0;
  370.  
  371.     if(orientation_ask)
  372.         {printf("Portrait or landscape orientation? ('p' or 'l', default %c): ",
  373.             portrait?'p':'l');
  374.         gets(buf); 
  375.         portrait |= strichr(buf, 'p');
  376.         landscape = !portrait;
  377.         }
  378.  
  379.     left=offset[0];
  380.     top=offset[1];
  381.     while(1)
  382.         {if(offset_ask)
  383.             {printf("\nEnter left and top margin in inches \n");
  384.             printf("                      (default %5.3f and %5.3f): ",left,top);
  385.             gets(buf); if(buf[0]) sscanf(buf,"%lf %lf",&left,&top);
  386.             }
  387.         if(left<0. || left>10.75)
  388.             printf("left margin outside valid range 0-10.75\n");
  389.         else if(top<0. || top>10.75)
  390.             printf("top margin outside valid range 0-10.75\n");
  391.         else if((portrait && left > 8.25) || (landscape && top > 8.25) || 
  392.                                                 (left > 8.25 && top > 8.25))
  393.             printf("no room left for plot!\n");
  394.         else break;
  395.         offset_ask = 1;
  396.         left=BMARGIN;
  397.         top=LMARGIN;
  398.         }
  399.  
  400.     w = size[0];
  401.     h = size[1];
  402.     
  403.     while(1)
  404.         {if(size_ask)
  405.             {
  406.             printf("\nEnter width and height of plot area in inches \n");
  407.             if(!portrait)
  408.                 printf("maximum for landscape orientation, %5.3f by %5.3f\n", 
  409.                                                     10.75 - left, 8.15 - top);
  410.             if(!landscape)
  411.                 printf("maximum for portrait orientation,  %5.3f by %5.3f\n", 
  412.                                                     8.15 - left, 10.75 - top);
  413.             printf("                         (default, %5.3f by %5.3f): ", w, h);
  414.             gets(buf); if(buf[0]) sscanf(buf,"%lf %lf",&w,&h);
  415.             }
  416.  
  417.         if(landscape) hmax = 8.15 - top; else hmax = 10.75 - top;
  418.         if(portrait) wmax = 8.15 - left; else wmax = 10.75 - left;
  419.                                 /* round to nearest .01" */
  420.         hmax = floor(hmax*100. + .5)/100.;
  421.         wmax = floor(wmax*100. + .5)/100.;
  422.         h = floor(h*100. + .5)/100.;
  423.         w = floor(w*100. + .5)/100.;
  424.  
  425.         if(w < .1 || w > wmax)
  426.             printf("width outside valid range 0.1 to %2.3f\n", wmax);
  427.         else if(h < .1 || h > hmax)
  428.             printf("height outside valid range 0.1 to %2.3f\n", hmax);
  429.         else if(w + left > 8.15 && h + top > 8.15)
  430.             printf("either width or height must be reduced\n");
  431.         else break;
  432.                             /* find suitable defaults for next time */
  433.         if(!portrait && top < 8.5 - LMARGIN)/* assume landscape orientation */
  434.             {h = 8.5 - top - LMARGIN;
  435.             if(left < 11. - TMARGIN) w=11. - left - TMARGIN;
  436.             else w = 11 - left;
  437.             }
  438.         else if(!landscape && left < 8.5 - RMARGIN)
  439.             {                            /* else assume portrait orientation */
  440.             w = 8.5 - RMARGIN - left;
  441.             if(top < 11. - BMARGIN) h = 11. - top - BMARGIN;
  442.             else h = 11. - top;
  443.             }
  444.         else if(!portrait && top<8.15) {h=8.15-top; w=10.75-left;}
  445.         else {h=10.75-top; w=8.15-left;}  /* maximize area */
  446.         size_ask = 1;
  447.         }
  448.     if(w + left > 11.) w = 11. - left;
  449.     if(landscape) 
  450.         {                /* landscape orientation */
  451.         if(h + top > 8.15) h = 8.15-top;
  452.         }
  453.     else
  454.         {                /* portrait orientation */
  455.         if(h + top > 11.) h = 11.-top;
  456.         }
  457.  
  458.     pixels_wide = w/UNIT;
  459.     pixels_high = h/UNIT;
  460.                     /* 
  461.                         Use 13 point font, which has height 13/72 = .181
  462.                         in (including an allowance for spacing between
  463.                         lines), assume height:width ratio of 2:1.  (Due
  464.                         to proportional spacing, actual character width
  465.                         is variable, from about .085 inch for lower
  466.                         case to about .103 for upper case.) This width is
  467.                         increased by 20% because it seems to be
  468.                         necessary to get proper superscript placement.
  469.                     */
  470.     char_height = 13./72/UNIT;
  471.     char_width = 13./72/2/UNIT*1.2;
  472.  
  473.     char_columns = pixels_wide/char_width;
  474.     char_rows = pixels_high/char_height;
  475.  
  476.     if(portrait)                        /* portrait orientation */
  477.         {best_width = (double)pixels_wide/pixels_high;
  478.         best_height = 1.;
  479.         }
  480.     else                                /* landscape orientation */
  481.         {best_width = 1.;
  482.         best_height = (double)pixels_high/pixels_wide;
  483.         }
  484.     TI(pixels_wide,"pixels_wide");
  485.     TI(pixels_high,"pixels_high");
  486.     TI(char_rows,"char_rows");
  487.     TI(char_width,"char_width");
  488.     TI(char_columns,"char_columns");
  489.     TR(best_width,"best_width");
  490.     TR(best_height,"best_height");
  491.  
  492.     sp = prelude1;
  493.     while(*sp) fputs(*sp++, plot_file);
  494. /*
  495.     PostScript's origin is at the bottom left corner of the 8.5x11 page.
  496.     "translate" and "rotate [CCW]" commands operate on the material
  497.     being drawn.
  498. */
  499.     if(portrait)                          
  500.         {fprintf(plot_file, "/setorigin { %3.3f inch %3.3f inch translate \n", 
  501.                         left, 11. - h - top); /* move to starting point */
  502.         bottom = 11. - h - top;
  503.         right = 8.5 - w - left;
  504.         }
  505.     else
  506.         {fprintf(plot_file,"/setorigin { %3.3f inch %3.3f inch translate \n", 
  507.                         top + h, left);       /* move to starting point */
  508.         fprintf(plot_file, "             90 rotate \n");    /* landscape */
  509.         bottom = 8.5 - h - top;
  510.         right = 11. - w - left;
  511.         }
  512.     fprintf(plot_file, "             0 0 m  } def \n\n");
  513.  
  514.  
  515.     fprintf( plot_file, portrait ? "%% portrait orientation\n\n" 
  516.                                     : "%% landscape orientation\n\n");
  517.     fprintf( plot_file, "%%   left margin: %4.3f in = %5.2f cm\n",
  518.                                                         left, left*2.54 );
  519.     fprintf( plot_file, "%%    plot width: %4.3f in = %5.2f cm = %5d pixels\n",
  520.                         pixels_wide*UNIT, pixels_wide*UNIT*2.54, pixels_wide );
  521.     fprintf( plot_file, "%%  right margin: %4.3f in = %5.2f cm\n\n",
  522.                                                         right, right*2.54 );
  523.     fprintf( plot_file, "%%    top margin: %4.3f in = %5.2f cm\n",
  524.                                                         top, top*2.54 );
  525.     fprintf( plot_file, "%%   plot height: %4.3f in = %5.2f cm = %5d pixels\n",
  526.                         pixels_high*UNIT, pixels_high*UNIT*2.54, pixels_high );
  527.     fprintf( plot_file, "%% bottom margin: %4.3f in = %5.2f cm\n",
  528.                                                         bottom, bottom*2.54 );
  529. /**/
  530.     sp = prelude2;
  531.     while(*sp) fputs(*sp++, plot_file);
  532.  
  533.     fprintf(plot_file, "%% initialization complete\n");
  534. }
  535.  
  536. static int allwhite(s) char *s;
  537. {    while(*s) if(!isspace(*s++)) return 0;
  538.     return 1;
  539. }
  540.  
  541. static text(s) char *s;
  542. {    int c;
  543.     if(allwhite(s)) return;
  544.     WAIT;
  545.     fprintf(plot_file, "cpt st m\nfont0 sf (");
  546.     while(c = *s++) 
  547.         {if(strchr("\\()", c) != NULL) 
  548.             fprintf(plot_file, "\\");        /* escape special characters */
  549.         fprintf(plot_file, "%c", c);
  550.         }
  551.     fprintf(plot_file, ") show \n");
  552.     cx=cy=-2000;
  553. }
  554.  
  555. static character(c) char c;
  556. {    char buf[2];
  557.     buf[0]=c; buf[1]=0;
  558.     text(buf);
  559. }
  560.  
  561. version()    /* return MS-DOS version number. Version 2.01 returned as 0x201 */
  562. {
  563. #ifdef __DESMET__
  564.     extern unsigned _rax;
  565.     _rax=0x3000;
  566.     _doint(0x21);
  567.     return ( (_rax&0xff)<<8 | (_rax&0xff00)>>8 );
  568. #else
  569. #include <dos.h>
  570.     return ( (_version&0xff)<<8 | (_version&0xff00)>>8 );
  571. #endif
  572. }
  573.  
  574. #ifdef __DESMET__
  575. /*    search environment for given string */
  576.  
  577. getenv(target) char *target;
  578. {    char buf[256],*s,t[25],*env, *malloc();
  579.     int nt,offset;
  580.  
  581.     s=t;
  582.     while(*target) *s++=toupper(*target++);
  583.     *s++= '='; *s=0;
  584.     nt = strlen(t);
  585.     offset=0;
  586.     _lmove(2,44,_showcs()-0x10,&env,_showds());
  587.     while(1)
  588.         {_lmove(256,offset,env,buf,_showds());
  589.         s=buf;
  590.         if(*s)
  591.             {/* printf("examining entry: %s \n",s); getchar(); */
  592.             if (strncmp(t,s,nt)==0) 
  593.                 {env = malloc(strlen(s+nt)+1);
  594.                 if(env == NULL) return NULL;
  595.                 return strcpy(env, s+nt);
  596.                 }
  597.             }
  598.         else return NULL;
  599.         offset+=strlen(buf)+1;
  600.         }
  601. }
  602. #endif
  603.  
  604. /*        finish - close down the graphics system     */
  605.  
  606. finish_graphics()
  607. {    if(plot_file != stdout)
  608.         {clear_graphics();
  609.         fclose(plot_file);
  610.         }
  611.     plot_file = stdout;
  612. }
  613.  
  614. clear_graphics()
  615. {    if(something_printed) 
  616.         fprintf(plot_file,
  617.         "stroke \n%%EndGraph\n%%end(plot)\n showpage grestore\n%%%%Trailer\n");
  618. /*
  619.     "%end(plot)" is a structure comment for the program DVIALW by Nelson
  620.     H. F. Beebe (Beebe@Science.Utah.Edu).  DVIALW is a program to
  621.     convert a TeX DVI file into PostScript for the Apple LaserWriter. 
  622.     This comment and the the "%begin(plot)" included in gps.h delimit the
  623.     portion of a GRAPHPS output file which is to be incorporated into a
  624.     TeX document.
  625. */
  626.     something_printed=0;
  627. }
  628.  
  629.  
  630. /*    pointers to optional functions (NULL if not implemented)    */
  631.  
  632. int    (*new_linestyle)()=set_style;    /* (*new_linestyle)(style) int style; */
  633. int    (*new_linewidth)()=set_width;    /* (*new_linewidth)(width) int width; */
  634. int    (*new_charsize)()=0;    /* (*new_charsize)(w,h) int w,h; */
  635. int    (*draw_marker)()=0;    /* (*draw_marker)(n) int n; */
  636.  
  637. #ifdef MAIN
  638.  
  639. main()
  640. {    char buf[100];
  641.     printf("Interface %s for the %s\n",interface_version,machine);
  642.     init_graphics();
  643.     printf("screen width %d pixels\nheight %d pixels\n",
  644.         pixels_wide,pixels_high);
  645.     printf("height:width ratio %f:%f\n",best_height,best_width);
  646.     printf("%d colors\n",max_color+1);
  647.     printf("primitive attributes...\n");
  648.     printf("color_count=               %d \n",prim_attr.color_count);
  649.     printf("intensity_count=           %d \n",prim_attr.intensity_count);
  650.     printf("intensities_in_hardware=   %d \n",prim_attr.intensities_in_hardware);
  651.     printf("hardware_linestyles=       %d \n",prim_attr.hardware_linestyles);
  652.     printf("software_linestyles=       %d \n",prim_attr.software_linestyles);
  653.     printf("linewidth_count=           %d \n",prim_attr.linewidth_count);
  654.     printf("linewidths_in_hardware=    %d \n",prim_attr.linewidths_in_hardware);
  655.     printf("linewidth_minimum=         %d \n",prim_attr.linewidth_minimum);
  656.     printf("linewidth_maximum=         %d \n",prim_attr.linewidth_maximum);
  657.     printf("hardware_pens=             %d \n",prim_attr.hardware_pens);
  658.     printf("software_pens=             %d \n",prim_attr.software_pens);
  659.     printf("charfont_count=            %d \n",prim_attr.charfont_count);
  660.     printf("charsize_count=            %d \n",prim_attr.charsize_count);
  661.     printf("charsize_in_hardware=      %d \n",prim_attr.charsize_in_hardware);
  662.     printf("charsize_minimum=          %d \n",prim_attr.charsize_minimum);
  663.     printf("charsize_maximum=          %d \n",prim_attr.charsize_maximum);
  664.     printf("hardware_markers=          %d \n",prim_attr.hardware_markers);
  665.     printf("software_markers=          %d \n",prim_attr.software_markers);
  666.     printf("pick_id_count=             %d \n",prim_attr.pick_id_count);
  667.     (*draw_line)(2,4,200,-400);
  668.     (*draw_line)(20,40,100,-200);
  669.     (*erase_line)(2,4,200,-400);
  670.     (*draw_line)(10,30,100,300);
  671.     (*draw_line)(10,40,500,890);
  672.     (*draw_line)(10,40,500,32);
  673.     (*draw_line)(10,1000,78,8900);
  674.     gotoxy(10,-20);
  675.     (*draw_text)(" ello\nDolly ");
  676.     (*draw_char)('H');
  677.     finish_graphics();
  678. }
  679.  
  680. #endif
  681.  
  682. maximum(a,b) int a,b;
  683. {    if (a>b) return a;
  684.     return b;
  685. }
  686.  
  687.