GraphiC Library

Table of Contents

Overall Organization

GraphiC functions have been classified into four levels:
0 - before initialization of GraphiC
1 - after initialization
2 - after the page layout and options have been defined<R>
3 - after the axes are defined
These levels indicate the order in which the calls should be made; the lower a function's level, the earlier in the program it should be called. These levels should be used as guides so that parameter setting routines will be called before the outines that use those parameters.

Each program containing GraphiC routines must be initialized and terminated using the routines bgnplot() and stopplot(). Generally each of these routines is called only once in the program.

Each GraphiC screen (a screen on the PC may contain several individual pictures) must also be initialized and terminated using the routines startplot() and endplot(), respectively. These obligatory routines put the color defaults, screen erasures, and other necessary information into the file containing the plot information.

We have provided a collection of sample programs to help you get started. These programs can be found in the chapter Example Programs. We always use one of the example programs as boiler plate for a new one.

To indicate functions that have changed or are new since the last version of GraphiC, or that are obsolete, we use different color backgrounds for the function name as follows:
NormalFunction (void)
Level 0
ChangedFunction (void)
Level 0
ObsoleteFunction (void)
Level 0
Obsolete functions are maintained in this version of GraphiC for backwards compatibility. However, you should update your code and replace these functions because they will be removed from the next release.

The same color conventions are used for changed or for obsolete text so that it will be easy for you to see.

Initialization Routines

In general, you should have only one call to the GraphiC initialization routine bgnplot(), and one call to the termination routine stopplot() in your program.

An exception to this rule occurs in OS/2, a multithreaded environment. GraphiC/OS2 allows you to call GraphiC from different threads in your program, and in this case, each thread should have its own initialization/termination sequence.

void bgnplot (Schar monitor, Schar screentype, char * filename)

GPC_MAIN (void)

void NewFile (char *newfile)

void startplot (color)

Accessing text mode after GraphiC starts

After GraphiC is initiated via a call to bgnplot(), GraphiC expects all screen output to be in a graphical form between the calls to startplot() and endplot(). However, you might also want to display numbers or other text-mode items as your program calculates. GraphiC has two different methods of doing this depending upon whether you are in a DOS or in a windowed environment.

void gpcTextMode (int on_off)


Plot Termination Routines

void DateIt (unsigned char font)

void DateItXY (float xinch, float yinch, unsigned char font)

int endplot (void)

void plotadd (void)

void stopplot (void)


Page and Axis Options

void acrop (int mode)

void area2d (float xinch, float yinch)

void autolegend (char on_off)

void axesoff (int noaxes)

void axnamhtfloat (inch)

void box (void)

void ColorKeyL (float minv, float maxv, int *intensity, int nintensity, float legllx, float leglly, float legurx, float legury, int labint, char * format, char fontc, float height, int angle)

void ColorKeyN (float *values, int *intensity, int nintensity, float legllx, float leglly, float llegurx, float llegury, int labint, char * format, char fontc, float height, intangle)

void cross (int iscross)

void CrossAt (float x, float y)

void fgrid (char lnstyle, int ndiv)

void frame (int frameon, int ftick)

void GPCClipRectangle (float llx, float lly, float urx, float ury, int units, int border)

void grid (int lnstyle)

void gwindow (float x0, float y0, float x1, float y1)

void legend (int marker, char *string, int style, float strhgt, int scolor)

void legpos (int entries, float xleg, float yleg, int border)

void metricunits (int on_off)

void numht (float inch)

void orel (float xorel, float yorel)

void page (float width, float height)

void pbox (void)

void pgshift (float xshift, float yshift)

void physor( float xphysor, float yphysor)

void rightax (int yright)

void PixPerUnit (int pixels)

void plotabsolute (int absolute_flag)

void PlotLength (float length)

void rotate (int isrot)

void SetLabelSpace (int axis, float factor)

void SetNameSpace (int axis, float factor)

void tickht (float height)

void tickout (int out)

void titlht (float inch)

void upright (int uplab)

void xfgrid (char lnstyle, int nxdiv)

void xgrid (int isgrid)

void xlab (int on_off, char * labstr[])

void xLabAng (int angle)

void xnamht (float inch)

void yfgrid (char lnstyle, int nydiv)

void ygrid (int isgrid)

void ylab (int on_off, char *labstr[])

void yLabAng (int angle)

void ynamht (float inch)

void zlab (int on_off, char * labstr[])

void zLabAng (int angle)


Simultaneous Plots

If you already have all the data needed to make several plots on a page, the best strategy is to follow the example in D2TEST.C and make several sequential calls to page(), making each plot as a complete entity. But, suppose you are running a long program that generates the data for several plots at once, and you would like to see the data on all the plots as they are being generated. In this case, the routines in SIMPLT.C can solve your problem. A sample program is given in the example FERMI.C.

In order to make simultaneous plots on one page, you need to call simuplot(num_of_plots) to specify the number of plots on a page. Then you call context() for each individual plot. You should make one call to page() for each context, and the area should be large enough to accommodate all of the subplots. Put this call in the first subplot.

The subplots are defined by calls to context(plot_number). The first time context() is called for a subplot, there should be a call to area2d() (if needed), and you should make all of the other calls needed to set up the axes
before making another call to context().

Then, each time you want to plot data points in a subplot, make a call to context(plot_num) and thenmake your usual call to curve() or other plotting function.

When you complete all of the subplots, make a call to simuplot(0) and then a single call to endplot() and stopplot(). This call to simuplot(0) is essential in order to free all of GraphiC's internally allocated memory.

GraphiC uses a temporary file for each context's TKF data, and these are combined sequentially into the actual .TKF file when simuplot(0) is called. If you abort a GraphiC simultaneous plot without cleaning up via a call to simuplot(0), the temporary files will be left on your PC. The name and location of the temporary files depends on your compiler and the version of GraphiC. For example, with Microsoft C in DOS, the files are in the root directory and are called 1, 2, 3, . . .

The simultaneous plotting mechanism can also be used any time you need to plot graphs with different attributes on the same space. For example you can set up a plot with several x and y axes, then change among the coordinate systems as needed. The example MULTI_Y.C shows how this is done.

In GUI environments, the context feature can be used to have simultaneous plots running in separate windows within a single thread. Each window will have its own menus and if desired, a separate TKF file pointer. If you use separate TKF file pointers, you will be able to print each window individually. To use this feature, call NewFile() and GPCWINCreate() inside of each context definition. The window for the first context should be the window created by bgnplot().

Simultaneous plot functions:

void context (int plot_number)

void simuplot (int numplots)


2-D Axes Routines

All of the routines that draw axes are level 2 calls that raise GraphiC to level 3.

GraphiC provides two types of axis routines:

  • User-scaled routines allow you to have full control over all aspects of the axis tick marks and number formats.
  • Self-scaling routines do most of the work for you, but you must present them with all of the data so that they can determine the proper scales and axis labels. Because GraphiC has a sophisticated algorithm to choose nice axis labels, it may change the number of axis divisions from the number you requested.
  • The routines that make the decisions about the labels use floats (as opposed to doubles) to calculate the step sizes and the rounded values given to the labels. Because floating-point precision is used, the range of your data cannot be too small compared with the size of your data. For example, if your data values range from 1,000,000. to 1,000,001. and you are taking 5 steps, the step size would be .2. With floating-point precision this step size would be too small to show when printing the labels. If
    (max_value - min_value)/max_value < 0.00004
    then your data cannot be autoscaled.

    If this situation exists you will get an error message to this effect and you will need to offset your data (by subtracting 1,000,000 in the above example). The same problem will occur using manual scaling [e.g., using graf()] since the above inequality also must pertain.

    Another problem will arise if all the values are the same in one of your axis arrays. (This can happen due to roundoff and precision problems.) In this case, GraphiC will set the minimum value to the constant value -1.0 and set the maximum value to the constant value + 1.0 A warning message will also be placed in the file GRAPHIC.ERR.

    Linear Axes

    void graf (char *xformat, float xori, float xstep, float xmax, char *yformat, float yori, float ystep, float ymax)

    void scales ([nt nxdiv, int nydiv, float *x, float *y, int npts)

    Logarithmic Axes

    void lglgscle (float *x, float *y, int npts)

    void loglog (float xori, float xmax, float yori, float ymax)

    void SetLogBase (double base_x, double base_y)

    void xlgscle (int nydiv, float *x, float *y, int npts)

    void ylgscle (int nxdiv, float *x, float *y, int npts)

    void xlog (float xori, float xmax, char *yformat, float yori, float ystep, float ymax)

    void ylog (char * xformat, float xori, float xstep, float xmax, float yori, float ymax)

    Labeling Routines

    void heading (char *title)

    void xname (char *xlabel)

    void yname (char *ylabel)

    Linear Functions

    void bar (int nxdiv, float *x, float *y, int npts, float bwid, int mode, int carray[], int typearray[])

    void curve (float *x, float *y, int npts, int sym)

    void curvfill (float *x, float *y, int npts, float*x1, float*y1, int npts1, int pcolor, int curves)

    void errorbar (float x, float xmin, float xmax, float y, float ymin, float ymax)

    void histogram (float *x, float *y, int npts, int type, int *colors)

    void scatplot (int dot)

    void staircase (float *x, float *y, float *xnew, float *ynew, int npts, int mode)


    Smith Charts

    Smith charts are maps of the complex plane that are used by electrical engineers to determine how impedances transform along a transmission line.

    Smith chart plotting functions:

    void getrho (float *rho, float *theta)

    void getrx( float *R, float *X)

    void plotrho (float rho, float theta)

    void plotrx (float R, float X)

    void smdraw (int lcolor)

    void smithcir (float u, float v, float radius)

    void smove ( float del)


    Polar Plots

    Polar plot functions:

    void polar (char mode)

    void polcurve (float *r, float *theta, unsigned dim, int sym)

    void polgrid (float rmax, float rmin, int mode, char *larray[], int dim, int ntheta, int color)

    void wedge (float rmin, float rmax, float thmin, float thmax, int pattern, int border)


    Contour Plots

    Contour plots can be drawn in conjunction with 3-D plots by following the instructions given under plane3d().

    In addition to drawing a contour plot in a plane of the 3-D workbox, you can draw contour plots as elevated or stacked contours. This can be done by establishing a 3-D workbox, calling plane3d(), and calling stack(1). This feature can be used to superimpose a contour plot on a 3-D surface. Stacked contours do not have hidden line removal activated.

    The following method of specifying line styles and colors will handle only the 16 basic IBM colors and is retained for compatibility purposes. It will be eliminated in the next major revision of GraphiC. Instead, set the lnstyle arrays to NULL and use a call to contcolor() before calling the contour-plotting function.
    All of the contouring routines use an array of three-digit coded numbers to set the line style and color for each contour ring. The first two digits of the number are 10 + the color number. The third digit is the line style number. For example, 233 sets the color to 13 and the line style to 3: 
             (int)(233/10) - 10 = color 
            233 - ((color + 10)*10) = line style.
    To use the current active color and line style use (char *)0 for the line style and color array argument or create an array with a single element equal to 0.

    GraphiC can also be used to create triangle plots. Triangle plots are a special kind of contour plot. They provide for the graphic display of an attribute of a three-component mixture. Each component is associated with a vertex. The fraction of that component is plotted on a line parallel to the opposite side. The position of the line is proportionally closer to the vertex depending on the relative amount of the component. Any two components determine the position of a point. GraphiC draws constant-value contours of the attribute.

    The user has two options for triangle plots. You can specify a functional relationship between the attribute and two of the parameters or you can provide a table of values. The contours cannot be labeled automatically because of the mapping scheme used to generate them. They can, however, have different colors and/or line styles, which can be displayed and identified in a legend box.

    Polar contour plots are created by setting up polar axes and making a call to polar() before your call to any contour-plotting routines. The x array in the contour plot corresponds to the radial direction in polar coordinates, and
    the y array corresponds to the angular direction in polar coordinates.

    Setting z-values in a user-supplied matrix or in a function return value to a special value (called Not A Number, or NAN for short) will tell the contour plotter that data is missing, and contours will not be drawn through the cells so marked.

    GraphiC allows you to define several types of NANs to allow you to represent data values that are missing,
    bad, or undefined. GraphiC ignores these values when doing contour plots and 3-D surface plots. As a result, your data can be defined on a non-rectangular domain.

    The various types of defined NANs are shown in the listing of MISSINGS.H. If you set data to NAN values, you must be sure that you do not compute using the NAN values or else a run-time error will result. Since the NAN macros are complicated, it is safest to test only simple variables to see if they are NANs. An example of  the use of NANs is given in the Introduction.

    Contour plotting functions:

    void conmat (float *zmat, float *x, int nx, float *y, int ny, float min, float step, float max, int *lnstyle, int labint)

    void conmat2 (float *zmat, float *x, int nx, float *y, int ny, float min, float step, float max, int *lnstyle, int labint)

    void conmatr (float *x, float *y, float *z, int npts, float xgmin, float xgmax, int nxpts, float ygmin, float ygmax, int nypts, float zorig, float zstep, float zmax, int *lnstyle, int labint)

    void conmatrNS (float *x, float *y, float *z, int npts, float xgmin, float xgmax, int nxpts, float ygmin, float ygmax, int nypts, float zorig, float zstep, float zmax, int *lnstyle, int labint)

    void contcolor (int *colors, int bord, int *line_styles)

    void contour (float (*fun)(float, float), float *x, int nx, float y, int ny, float min, float step, float max, int *lnstyle, int labint)

    float GetContour (int *size, float **x, float **y, float level)

    void lconmat (float *zmat, float *x, int nx, float *y, int ny, float *level, int *lnstyle, int nlevel, int labint, char *format)

    void lconmat2 (float *zmat, float *x, int nx, float *y, int ny, float *level, int *lnstyle, int nlevel, int labint, char *format)

    void lcontour (float (*fun)(float,float), float *x, int nx, float *y, int ny, float *level, int nlevel, int *lnstyle, int labint, char *format)

    void patchmat (float *zmat, float*x, int nx, float *y, int ny, float minv, float maxv, int type, int *intensity, int nintensity, int border, float legllx, float leglly, float legurx, float legury, int labint, char *format, char font,  float height, int nsmear)

    void PatchMatL(float *zmat, float*x, int nx, float *y, int ny, float *minv, float *maxv, int type, int *intensity, int nintensity, int nsmear)

    void stack (int stacked)


     Triangle Plots

    Triangle plots provide for the graphic display of an attribute of a three-component mixture. Each component is associated with a vertex. The fraction of that component is plotted on a line parallel to the opposite side. The position of the line is proportionally closer to the vertex depending on the relative amount of the component. Any two components determine the position of a point. This example is in the file TRITEST.C

    Triangle plot functions:

    void trifun( float (*fun)(float,float), int dim, float zmin, float zstep, float zmax, int *lnstyle, int border)

    void aname (char *label)

    void bname (char *label)

    void cname (char *label)

    void trinamht(float height)


     Plume Plots

    Plume plots allow you to represent a third dimension by using patches of various colors on a set of two-dimensional axes. For example, an airplane might fly back and forth over a region and measure pollution at various places along the route, and display the concentration of the pollutant as shown in the plot below.

    Because these routines use the GraphiC symbol() function, the colored patch can be represented by any of the GraphiC symbols, and these functions can be used with any of the two-dimensional axes (i.e., linear, logarithmic, polar, error function).

    A subsequent call to ColorKeyL() or ColorKeyN() should be used to plot the color key legend as shown below. Depending upon where you wish to place the legend, you might want to move the axes via a call to physor().

    This example uses PlumePlotN() and ColorKeyN() to provide more resolution in the higher pollution areas. In this example, data exists with z < -2.2, and the maximum value is less than z = +2.2. The vector of color demarcation values was selected to yield even values for the color key labels. The code for this example is in PLUME.C.

    Plume plot functions:

    void PlumePlotL (float *x, float *y, float *z, int dim, float *minv, float *maxv, int symnum, float symheight, float *intensity, int nintensity)

    void PlumePlotN (float *x, float *y, float *z, int dim, float *values,  int symnum, float symheight, float *intensity, int nintensity)


     Three-Dimensional Plots

    GraphiC has the ability to do excellent plots of 3-D curves and surfaces. The output page is apportioned the same way as for 2-D plots, by calls to rotate(), page(), and area2d(). However, because of the projection of a 3-D plot into a 2-D space, only relative units can be used. GraphiC will always make the plot as large as possible to fit within the window defined in area2d().

    Begin by defining the three sides of a workbox in 3-D space using volm3d(), thus determining the relative lengths
    of the three axes. Only the ratios of these lengths are important. Next, you must define the position of the viewer in the units of your workbox [vuabs() or vuangl()] or in user units [view()]. The view point must be outside the workbox. Picking a viewpoint which is closer to the plot will NOT make the plot larger; it will only increase the perspective distortion unless you have called sclfix().

    Finally, you must specify the variable ranges for the three axes. GraphiC does not have a self-scaling 3-D routine; instead, it rounds off the steps you specify to minimize the complication of the axis numbers. This process is done in graf3d().

    Curves may be plotted in the 3-D space with curv3d(), and surfaces may be displayed with surfun(), surmat(), surmatc(), or surmat2c(). Hidden line removal will not work with curv3d(), or stacked contours.

    Hidden line removal works by establishing upper and lower horizons for each pixel column. As a surface is being plotted, the horizons are updated so that for each column the upper horizon is set to the highest point of the surface and the lower horizon is set to the lowest. When the surface is finished, the horizons define the outline of the surface.

    The 3-D surface-plotting routine can be restricted to a portion of the rectangular x-y plane by replacing the matrix values with NANs or returning a NAN from the surface-defining function. NANs are defined in MISSINGS.H and discussed in more detail in the section on contour plots; their use is illustrated in the example in the Introduction.

    Waterfall plots can be produced two ways. You can call the WaterfallCurve() function to draw individual curves on the plot or you can pass all of the data in a matrix to WaterfallPlot().

    3-D plotting functions:

    void bcolor (int botcolor)

    void box3d (void)

    void curv3d (float *x, float *y, float *z, int npts)

    void d3bars (float barson)

    void d3base (int isbase, int color)

    void d3color (int *array, int nlevel, int mesh)

    void d3colorN (float change, int *colors, int nlevel, int mesh)

    void d3head (char *title, int place)

    void d3line (float xf, float yf, float zf, float xt, float yt, float zt)

    void d3pltfnt (float x, float y, float z, char *string, float height, int angle)

    void d3scale (float x, float y, float z, int *xp, int *yp)

    void d3symbol (float x, float y, float z, int sym, int connect)

    GPCHorizonInit (void)

    void graf3d (float xorig, float xstep, float xmax, float yorig, float ystep, float ymax, float zorig, float zstep, float zmax)

    void nohide (int visible)

    void panel3d (float *x, float *y, float *z, int nsides, int pattern, int border)

    void sclfix (isfixed)

    void surfun (float (*zfun)(float,float), int ixpts, float xdel, int iypts, float ydel)

    void surmat (float *zmat, int xdim, int ydim)

    void surmat2 (float *zmat, int xdim, int ydim)

    void surmatc (float *zmat, int xdim, int ydim, int ixpts, int iypts)

    void surmatc2 (float *zmat, int xdim, int ydim, int ixpts, int iypts)

    void surmatr(float *x, float *y, float *z, int npts, float xgmin, float xgmax, int nxpts, float ygmin, float ygmax, int nypts)

    void surmatrS(float *x, float *y, float *z, int npts, float xgmin, float xgmax, int nxpts, float ygmin, float ygmax, int nypts)

    void survis (char *which)

    void tcolor (int topcolor)

    void view (float xvu, float yvu,float  zvu)

    void vuabs (float xvu, float yvu, float zvu)

    void vuangl (float phi, float theta, float radius)

    void volm3d (float xlength, float ylength, float zlength)

    void WaterfallCurve (float *x, float y, float *z, int npts)

    void WaterfallPlot (float *x, float *y, float **z, int nx, int ny)

    void x3name (char *name)

    void y3name (char *name)

    void z3name (char *name)

    2-D Plots in a 3-D Plane

    The entire range of plotting functions is available to plot in a plane defined by the calls to the 3-D plotting functions. Once the 3-D workbox has been defined, you can use these functions to plot 2-D graphs, lines, curves, or text in the plane you define. This feature allows you to draw projections of a surface onto a wall of the workbox or draw a contour plot that corresponds to the surface in the x-y plane at any value of z.

    void d3grid (int subdiv, int toplab)

    void plane3d (int plane, float position, int hide)


     Four-Dimensional Plots

    Four-dimensional plots allow you to represent a function of three variables in a three-dimensional plot. A four-dimensional (4-D) plot consists of a line from the x-y plane to the x,y,z data point, a symbol (optional) at the x,y,z data point, and a rectangular volume representing the 4-D data.

    The length of the edges of the rectangular volume are proportional to the cube root of the volume. The normalization of this volume is determined by the user specifying vmax, the maximum volume expected. The cube root of this value will yield an edge that is 1/10 the length of the three axes. Therefore, the rectangular volume will have the same aspect ratio as the 3-D work box.

    The rectangular volume plotted at each point, v, represents the function v(x, y, z). The code to create this example is D4TEST,C.

    4-D plotting functions:

    void Plot4d (float *x, float *y, float *z, float *v, int npts, float vmax, int sym)

    void Plot4dPnt (float x, float y, float z, float v, float vmax, int sym)


     Pie Charts

    Pie chart plotting functions:

    void pieplot (int nslices, float *seg, int *clr, float *offset, char caption[], float size, int border, int txtclr)


    Box and Whiskers Plots

    Box and whiskers plots display the statistical spread of multiple y-data points for a given value of x. If many such points exist, plotting all of them would result in a dense mass of points which would hide the underlying distribution's properties. Five percentiles of the distribution are displayed in this plot as shown below:
    The outliers often represent problems with the data or their analysis and may be displayed or suppressed. If a percentile falls between two y data points, GraphiC linearly interpolates between them. Box and whiskers plots lose their meaning if there are fewer than 10 data points for a given x-value since the five defined percentiles tend to collapse upon each other.

    Box and whiskers plotting function:

    void BoxPlot (float x, float *y, int ydim, int outlier, int symnum, floatwidth)


    Error Function Plots

    The x axis of an error function (ERF) plot is scaled on cumulative percentage. The y axis is scaled linearly. Results
    for a normal distribution (bell curve) are expected to be a straight line on the ERF grid. A typical example of the use of an error function plot is shown below.
    This example of an error function plot shows that the head sizes of boys form a normal distribution. 
    The code for this example is in ERFTEST.C.

    Error function plotting routines:

    void erfcurve (float *x, float *y, int npts, int sym)

    void erfgrid (float ymin, float ystep, float ymax, char *yformat)

    void erfscales (int nydiv, float *y, int npts)

     Line-Drawing Routines

    Functions for drawing lines and curves:

    void circle (float xpos, float ypos, float radius, float theta1, float theta2)

    void ellipse (float xc, float yc, float xr, float yr, float rotation, float th1, float th2, char degrees, int units)

    void fillellipse (int on_off, int pattern, int border, int units)

    void linch (float xfinch, float yfinch, float xtinch, float ytinch, int newcurve)

    void line (int xfrom, int yfrom, int xto, int yto, int newcurve)

    void radlin (float xpos, float ypos, float rad1, float rad2, float theta)

    void ucircle (double xpos, double ypos, double radius, double theta1, double theta2)

    void uline (float xfrom, float yfrom, float xto, float yto, int newcurve)

    void uradlin (float xpos, float ypos, float rad1, float rad2, float theta)

    void uradlinp (float xpos, float ypos, float rad1, float rad2, float theta, int axis)

    void uvector (float xfrom, float yfrom, float xto, float yto, float ltow, float size, char *type)

    void vector (float xfrom, float yfrom, float xto, float yto, float ltow, float size, char *type)


     Line and Symbol Styles

    These routines allow you to change the sizes, dash style, and thickness of lines and curves and control symbol selection.

    Line and symbol functions:

    void dashf (int style)

    void symbol (float x, float y, int symnum)

    void syminch (float x, float y, int symnum)

    void symht (float height)

    void sympick (int symnum)

    void tcurve (int width)

    void ticurve (float width)

    void tline (int width)

    void tiline (float width)



     GraphiC supports three sets of colors:

    We recommend using the new GraphiC RGB colors unless you need to retain IBM or Tektronix compatibility. The GraphiC RGB colors include the standard IBM colors (200215) and a 16-level gray scale (216231).
    The next 216 colors correspond to all combinations of six steps each in Red, Green, and Blue.

    The GraphiC colors may be viewed by PLAYing PATRN256.TKF, and the Tektronix dithered colors may be viewed using PATTERN.TKF.

    When specifying color for panels, to retain compatibility with the Tektronix 4105 protocol, the IBM colors are negative, and the range 116 contains patterned fill choices. If you specify the IBM colors between 200 and 215, you need not worry about this distinction.

    When output devices cannot support extended colors, GraphiC uses dither patterns to approximate the color.
    In order to use dither patterns on lines, the line width will be increased automatically by GraphiC.  Be sure that your color board can support the colors you select. For example, the IBM EGA adaptor requires 256 kb of video memory to use 16 colors, and the high-resolution 256-color drivers may require up to 2Mb of video memory.

    There are many representations of color that are used for different purposes. GraphiC uses the RGB (red, green, blue) system which is most appropriate for video systems.  GraphiC provides routines to convert colors from one system to another, or for matching RGB values to the closest GraphiC color.

    In general, color choices are sticky GraphiC will continue to use the color specified by a call to color() until
    another call to color() comes along. Some routines accept colors in their argument list, but GraphiC always restores the color that was active before the routine was called. You should be sure to make a call to color() at the start of each GraphiC frame [after each call to startplot()] to place the initial default color into the TKF file. Otherwise, if the file is replayed, the color at the end of the file might be used for the initial graphic elements.

    Functions that manipulate colors:

    void color (int value)

    void GRCtoIBM (int i, int rgb, int *IBMcolor)

    void HLStoRGB (int h, int l, int s, int *r, int *g, int *b)

    void penchg (int mode)

    void RGBtoCMY (int r, int g, int b, int *c, int *m, int *y)

    void RGBtoCMYK (int r, int g, int b, int *c, int *m, int *y int *k)

    int RGBtoGPC (int r, int g, int b, int *IBMcolor)

    void RGBtoHLS (int r, int g, int b, int *h, int *l, int *s)

    int RGBtoIBM (int rgb[3])

    Text Routines

    Text plots are set up with calls to bgnplot(), startplot(), rotate(), and page(). A further call to tmargin() is also required. Each screen plot is ended with a call to endplot().

    The same fonts that are used to label plots may be used to write legends or to make text viewgraphs for presentations. A large selection of fonts is available. Any four of them may be active at once. To use these fonts, you should be aware of how the font routines are implemented.

    Each font runs from ASCII character 32 (a space) through 199 (there is no character 127). Each character is stored as a series of vectors so that it may easily be changed in size or rotated. Characters may be plotted in any height and at any angle in one-degree increments from the horizontal. They may be skewed to the right or to the left, and their aspect ratio may be changed. The thickness of the lines that make up the character may be changed, as well as the color of the character. Strings also may be plotted along an arc.

    Tabs may be embedded into strings by using an ordinary tab character (ASCII 9). The tabs are expanded into the number of spaces determined by tabspace() and do not cause a jump to a particular column. Data and text may be combined into a string by using the sprintf() C library routine. The active fonts may be changed at any time by calling font(). A font selection character must be used at the beginning of every string; otherwise, the last active font will be used. Initially, the first font listed in the call to font() will be active.

    String location

    To make your text look attractive, you can determine where to plot a string by finding its half-width [with strwidth()] and determining the plotting position accordingly.

    The string location is always the coordinates of the lower left-hand corner of the first character in the string, with the string upright. However, this location may be specified in two ways: pltfnt()  plots the string at the x,y coordinates used in your plot. prtfnt() prints the string at a location x inches (or cm) from the left edge of the picture and y inches (or cm) from the bottom edge.

    All measurements for string size and placement are in absolute units on a full page unless setscale(1) is called. With the call to setscale(), dimensions will scale with the page size as specified with the call to page().

    For producing text slides, use the routines ctline(), rtline(), ltline(), and lcrline() to center, left, and /or right justify lines of text.

    Super- and subscripts

    GraphiC supports unlimited levels of super- and subscripts in a manner that is very easy to use. Each level of script is plotted in a smaller-sized font. The size may be controlled via scrht() and the offset by scrshft().

    To make a superscript, put the letters to be elevated in square brackets. To make a subscript, put the letters to be lowered in reversed square brackets. For example, to plot

    you would use the string "a[b]]c[". Nesting of scripts within each other is allowed, but at the end there should always be an equal number of left and right square brackets. In order to print a square bracket, you must precede it by the NULL symbol, an @ sign (use @@ to print an @ sign). Thus, to print x[t] you should enter it as x@[t@].

    Although we think that these control characters make intuitive sense and produce easy-to-read strings, you may
    change them by calling supsym(), subsym(), and nullsym(). The GraphiC escape symbols lose their meaning if symoff() is called.

    Text color

    The font routines will use the current active color set by a call to color(). You can change the color within a string by using a | followed by the number of the color you want. An additional | is also needed after the number. Here is an example:
    To print a | use @|.

     Text symbols and their meaning

    enter subscript; leave superscript
    leave superscript; enter subscript
    widen characters
    skew characters
    thicken characters
    change colors to the IBM color number following the |
    the number must be followed by another |
    cancel special meaning of the next character

    Text functions:

    void charspc (int width)

    void circtxt (float x, float y, float r, char *string, float height, float angle)

    void ctline (char *string, float height)

    void fbox (int boxon, float size)

    void fillfont (char fill)

    void fntchg (char symbol)

    void G_CDECL font(int nfont, ...)

    void fontfill (int fill, int fill_pattern, int border_color)

    void GPC_GETS (char *prompt, char *buf, int nbytes)

    void gpcGetCharWidth (unsigned char font, unsigned char nchar, int *width)

    void gpcGetWidestChar (unsigned char font, unsigned char *nchar, int *width)

    void gtext (char mode)

    void GTfont (int font_number)

    void lcrline (char *lstr, float hl, char * cstr, float hc, char *rstr, float hr)

    void linesp (float ratio)

    void lmargin (float marginch)

    void ltline (char *string, float height)

    void nullsym (int symbol)

    void pltfnt (float x, float y, char *string, float height, int angle)

    void putlabel (char *string, float xpos, float ypos, float height, int border, int units)

    void rmargin (float inch)

    void rtline (char *string, float height)

    void scrht (float factor)

    void scrshft (float shift)

    void setscale (int scflag)

    void setspacing (int char_space, unsigned char font)

    void skew (float skewfac)

    float strwidth (char *string, float height)

    void subsym (char symbol)

    void supsym (char symbol)

    void symoff (int on_off)

    void tabspace (int space)

    void tfont (int hwid)

    void tmargin (float marginch)

    void widen (float widfac)


    Cross Hairs

    The cross-hairs feature lets you do several things with your plot after it has been drawn. In cross-hair mode it is possible to read point values in inches, user units or pixels,to  mark point values for future use, or to draw lines from point to point.

    Cursor functions:

    void curson (int srow, int scol, float **fx, float **fy, int *find)

    void curvefollow (int srow, int scol, float *x, float *y, int npts)


    Plot Insertion

    GraphiC has the ability to allow you to insert one GraphiC plot within another plot.

    void insert (char *readfile, int picnum, float llx, float lly, float ysize, int irot)


    Program Timer

    Timing functions:

    void set_time (char timer)

    char *get_time (char timer)


    Character Input Routines

    These routines are not new, but we have documented them because they may be used in your programs to obtain keyboard input. None of these functions displays the characters entered at the keyboard.

    In OS/2, these routines are only activated when the menu is not active, i.e., between startplot() and endplot().

    Character input functions:

    int ciq (void)

    unsigned int cstsq (void)




    Character Output Routines

    These routines are used to display text on the graphic screen using an 8 ´ 10 pixel matrix font. The routines are very fast, and they put no information into the TKF file. Thus, they cannot be printed. Because the font is based on pixels, the size of the characters will depend upon the screen resolution.

    These routines are not available in OS/2.

    void putsgq (char *string, int row, int col)

    void lclrq (int row, int minl, int maxl)

    Text Mode

    Extensive amounts of text should be output in text mode. See the previous discussion to learn how to access text mode, and what restrictions must be observed.\

    GPC_PUTS (char * string)

    GPC_SPUTS (char *string)


    Statistical Functions

    int crosscorrelate (float *x, float *y, float *cvec, int dim, int avg)

    float mean (float *x, int xdim)

    float median( float *x, int xdim)

    float StdDev (float *x, int xdim)

    float variance (float *x, int xdim)



    int InterpolateZ (float *x_in, float *y_in, float *z_in, int npts, float xmin, float xmax, int nxg, float ymin, float ymax, int nyg, float **z_out)

    void rfit (float *x, float *y, intnpts, int nits, float sfact, int nout, float *xout, float *yout)

    int smear (float *minout, int nx, int ny, int nsmear)

    void spline (float *x, float *y, int n, int n1, float s1, float s2, float *xn, float *yn)

    void spline3 (float *x, float *y, float *z, int nx, int ny, int n1x, int n1y, float *xn, float *yn, float *zn)

    Matrix Routines

    void matsolve (double **coeff , int n, double *vector)

    void matinverse (double **input, double **output, int n)

    Panel Filling

    To use the panel filling routines you need to remove the comment delineators from the ends of
    /*#define PANEL*/
    in USER.H before compiling PANFIL.C, CNTPLT, and SVC.C. Filled fonts use the panel filling code; therefore, it is necessary to define PANEL if filled fonts are to be used.

    In addition to solid color fills, GraphiC provides a choice of 16 geometric patterns, 125 dithered patterns, and 248 RGB color combinations. These patterns can be viewed by using PLAY to display the files PATTERN.TKF and PATRN256.TKF.

    Panel filling functions:

    void panel (float *x, float *y, int nsides, int pcolor, intborder)

    void panelinch (float *x, float *y, int nsides, int pcolor, int border)

    void panel3d (float *x, float *y, float *z, int nsides, int pattern, int border)

    void panproc (void)

    Memory Routines

    GraphiC provides a number of routines to allocate, reallocate and free memory. We strongly advise using the GraphiC memory-allocation routines because they automatically provide the required actions on all the platforms supported by GraphiC. In addition, the GraphiC memory routines provide valuable debugging options to prevent memory leaks and to check boundaries.

    The debugging options are contained in the routine MEMORY?.C. Your code will run more slowly when memory debugging options are turned on, so be sure to turn them off for production code.

    If TESTMEM is defined in USER.H, GraphiC will keep track of all memory allocated and freed using these routines
    in a linked list. When you call stopplot(), this list will be checked and if there is any unfreed memory, a message will appear. If TESTMEM is defined, GraphiC keeps track of the file and line number of each call to gpcalloc(), gpcfree(), and gpcrealloc(). In addition, a guard byte is placed at the end of every memory block and set to 0xff. This byte is checked when the block is freed to be sure it was not changed. The TESTMEM option will help you to detect memory leaks, uninitialized pointers, and dimensioning problems. The GraphiC library must be recompiled whenever you change the TESTMEM switch.

    TESTMEM has no effect in GraphiC/OS2. But, all memory allocated using these routines will be freed in stopplot().

    In GraphiC/286, if TESTMEM2 is defined in MEMORY2.C, GraphiC will allocate every piece of memory in its own selector. Since the allocated memory is just long enough to accommodate the request, reading or writing past the end of the memory block will generate a protection fault, and the compiler's debugger will allow you to locate the error.

    If TESTMEM3 is defined in MEMORY2.C, GraphiC will do a heap check of the compiler's heap each time gpcalloc(), gpcfree() and gpcrealloc() are called.

    GraphiC memory routines:

    void **dim2 (int row, int col, int size)

    void **free2( vois ***mem_ptr)

    void * TYPE gpcalloc (size_t nobj, size_tsize)

    void TYPE gpcfree (void **mem_ptr)

    void * TYPE gpcrealloc (void * mem_ptr, size_tsize)

    long HowMuchMem (void)

    File Routines

    The GraphiC file routines operate much like normal C routines, but they are aware of the GraphiC environemnt variables and they allocate larger buffers for speedier i/o.

    GraphiC file routines

    FILE *gfopen (char *filename, char *mode, size_t bigbuff)

    void NewFile (char *tekfile)

    void TKFSegmentEnd( int save_seg)

    void TKFSegmentStart (void)


    Error Handling

    GraphiC 7 has improved error handling. If your program terminates while in graphics mode, GraphiC will return to text mode and attempt to give you useful information about the problem. You can extend GraphiC's error-handling capability  by adding your own messages to the file MESSAGES.DAT and running MESGTAB.EXE.

    Since MESSAGES.DAT contains all of GraphiC's prompts and messages, you can translate this file to create foreign-language versions of your software.

    Handlers are included for Ctrl-C, Floating-Point Errors (FPE), Abnormal Termination (ABORT), Math Errors, and (for GraphiC-286 only) General Protection (GP) Fault. You can modify or disable any of these handlers by changing the appropriate BAUX???.C file.

    GraphiC/OS2 does not install any error handlers.

    The matherr() function and Microsoft C

    GraphiC defines a matherr() function for catching certain errors from the compiler's math package. Because we are redefining a C library function, the /NOE switch is required with the Microsoft Linker (LINK). This option disables LINK's ability to check for duplicate symbols. If you need this capability, you can disable GraphiC's matherr() function. Just change the definition of G_MATHERR from 1 to 0 near the top of BAUX???.C.

    GraphiC-286 and Borland C++

    The GraphiC-286 interrupt handlers now work with Borland C++. However, if you use the PharLap 286 | DOS Extender Lite, which comes with Borland C++, interrupt handlers are not supported. In this case, you will need to disable the code which installs these handlers in BAUX286.C. You may do this by uncommenting the definition
    of LITE286 near the top of BAUX286.C.


    Printer Output

    Printer output may be obtained interactively. After the picture is drawn there will be a beep, at which time you can enter the appropriate response. For a detailed description of the keyboard responses see the section Graphics Output.

    GraphiC can produce color separations suitable for four-color printing. Thus, if you wish your program to work in all environments, do not use command-line arguments. Under DOS and OS/2, GPC_MAIN() is defined as main() so.In order to support other than the 16 pure colors, it is necessary that objects in the separations be printed in shades of gray. Only PostScript devices support this capability, so you can produce separations by printing to a PostScript printer or converting the output to PostScript. Alternatively, GraphiC's support for PostScript Level 2 means that such files are importable into desktop publishing packages such as Ventura Publisher and they can produce the separations.

    After a plot is drawn, entering an s will turn on separations (cyan, magenta, yellow, black) for the next picture. Crop marks are added at the corners of the plots to allow the printer to align the four pictures for exact color registration. The color of each separation is also printed outside of the plot area.

    The following routines allow you to output to the printer from within your code.

    void hardcopy (char type)

    void SetDefaultPrinter (int printer_num)

    Utility Routines

    void blank (char attr)

    void gpcBeep (int freq, int duration)

    GPCSetBeepDefaults (int freq, int duration)

    int intopix (float inch)

    void minmax (float *min, float *max, float *x, int npts)

    float pixtoin (int pix)

    void settolerance (float tolerance)

    void usertoinch (float x_in, float y_in, float *x_inch, float *y_inch)

    void usertopix (float x_in, float y_in, float z_in, int *x_pix, int *y_pix)

    Utility Programs