NAME
pslib v3.2 - A PostScript based plotting library
DESCRIPTION
pslib was created to make the generation of PostScript page
description code easier. It is a library that contains a
series of tools that can be used to create plots. The
resulting PostScript code is ASCII text and can be edited
using any text editor. Thus, it is fairly easy to modify a
plot file even after it has been created, e.g., to change
text strings, set new gray shades or colors, experiment with
various penwidths etc. pslib is written in C but now
includes FORTRAN bindings (thanks to John Goff, WHOI) and
can therefore be called from both C and FORTRAN programs.
To use this library, you must link your plotting program
with pslib.a. pslib is the core of the GMT SYSTEM and XY
graphics programs. pslib output conforms to the Adobe
Encapsulated PostScript File Specification Version 3.0
(EPSL), and may be used as EPS files and inserted into, say,
a Word document on a Mac. See Appendix F in the Technical
Reference for detailed instructions.
Before any pslib calls can be issued, the plotting system
must be initialized. This is done by calling ps_plotinit,
which defines macros, sets up the plot-coordinate system,
scales, and [optionally] opens a file where all the
PostScript code will be written. Normally, the plot code is
written to stdout. The measure unit for sizes and positions
can be set to be centimeter, inch, or m. When all plotting
is done, you must terminate the plotting system by calling
ps_plotend.
pslib uses the direct color model where red, green, and blue
are given separately, each must be in the range from 0-255.
If red < 0 then no fill operation takes place. Most plot-
items can be plotted with or without outlines. If outline
is desired (i.e., set to 1), it will be drawn using the
current linewidth and pattern. pslib uses highly optimized
macro substitutions and scales the coordinates depending on
the resolution of the hardcopy device so that the output
file is kept as compact as possible.
A wide variety of output devices that support PostScript
exist, including laserwriters (color or monochrome) and
workstations running PostScript based window systems like
SUNs OpenWindows. xnews (part of OpenWindows) or
ghostscript (public domain) can be used to create raster-
files at a user-defined resolution (DPI), making it possible
to render PostScript on a Versatec and other non-PostScript
raster devices. Regular SUN rasterfiles created under NeWS
from PostScript files can be sent to a variety of color
hardcopy units. Check the devices available on your
network.
FUNCTION CALLS
The following is a list of available functions and a short
description of what they do and what parameters they expect.
All floating point variables are expected to be double
(i.e., 8 bytes), whereas all integers are assumed to be 4
bytes long. All plotting functions are declared as func-
tions returning an int. Currently, the return value is
undefined.
void ps_arc (x, y, radius, angle1, angle2, status)
double x, y, radius, angle1, angle2;
int status;
Draws a circular arc centered on (x,y) from angle
angle1 to angle2. Angles must be given in decimal
degrees. If angle1 > angle2, a negative arc is
drawn. status is a value from 0 through 3. 1
means set new anchor point, 2 means stroke the
circle, 3 means both, 0 means none of the above.
void ps_axis (xpos, ypos, length, startval, stopval,
tickval, label, anotpointsize, side)
double xpos, ypos, length, startval, stopval, tickval;
int anotpointsize, side;
char *label;
Plots an axis with tickmarks, annotation, and
label. xpos, ypos, and length are in inches (or
cm or meters), anotpointsize in points (72 points
= 1 inch), else data units are used. side can be
0, 1, 2, or 3, which selects lower x-axis, right
y-axis, upper x-axis, or left y-axis, respec-
tively. labelpointsize = 1.5 * anotpointsize. A
negative tickval will reverse the sense of posi-
tive direction, e.g., to have the y-axis be posi-
tive down.
void ps_circle (xcenter, ycenter, diameter, rgb, out-
line)
double xcenter, ycenter, diameter;
int rgb[3], outline;
Plots a circle and fills it with the specified
color. If outline == 1, the outline will be drawn
using current pen-width and -pattern.
void ps_clipoff ()
Resets the clip path to what it was before the
last call to clipon.
void ps_clipon (xarray, yarray, npoints, rgb, flag)
double xarray[], yarray[];
int npoints, rgb[3], flag;
Sets up a user-definable clip path. Plotting out-
side this polygon will be clipped until ps_clipoff
is called. If red >= 0 the inside of the path is
filled with the specified color. flag is used to
create complex clip paths consisting of several
disconnected regions, and takes on values 0-3.
flag = 1 means this is the first path in a multi-
segment clip path. flag = 2 means this is the
last segment. Thus, for a single path, flag = 3.
void ps_colorimage (xpos, ypos, xlength, ylength,
buffer, nx, ny)
double xpos, ypos, xlength, ylength;
unsigned char buffer[];
int nx, ny;
Plots a 24-bit true color image using rgb colors.
Similar to ps_image except bits is fixed to be 8.
The rgb triplets are stored in buffer as
rgbrgbrgb... This functions sets up a call to the
PostScript colorimage operator which is not imple-
mented in all drivers.
void ps_colortiles (x0, y0, xlength, ylength, buffer,
nx, ny)
double x0, y0, xlength, ylength;
int nx, ny;
unsigned char buffer[];
Plots a true color image based on individual color
tiles. x0, y0 is the location of the lower left
corner of the image in inches. xlength, ylength
is the image size in inches. buffer contains rgb
triplets stored as rgbrgbrgb... nx, ny is the
image size in pixels.
void ps_command (text)
char *text;
Writes a raw PostScript command to the PostScript
output file, e.g. "1 setlinejoin".
void ps_comment (text)
char *text;
Writes a comment (text) to the PostScript output
file, e.g. "Start of graph 2".
void ps_cross (xcenter, ycenter, diameter)
double xcenter, ycenter, diameter;
Plots a cross at the specified point using current
pen-width and -pattern that fits inside a circle
of given diameter.
void ps_diamond (xcenter, ycenter, diameter, rgb, out-
line)
double xcenter, ycenter, diameter;
int rgb[3], outline;
Plots a diamond and fills it with the specified
color. If outline == 1, the outline will be drawn
using current pen-width and -pattern. The symbol
will fit inside a circle of given diameter.
void ps_ellipse (xcenter, ycenter, angle, major, minor,
rgb, outline)
double xcenter, ycenter, angle, major, minor;
int rgb[3], outline;
Plots a ellipse with its major semiaxis rotated by
angle degrees and fills it with the specified
color. If outline == 1, the outline will be drawn
using current pen-width and -pattern.
void ps_flush ()
Flushes the output buffer.
void ps_hexagon (xcenter, ycenter, diameter, rgb, out-
line)
double xcenter, ycenter, diameter;
int rgb[3], outline;
Plots a hexagon and fills it with the specified
color. If outline == 1, the outline will be drawn
using current pen-width and -pattern. The symbol
will fit inside a circle of given diameter.
void ps_image (xpos, ypos, xlength, ylength, buffer,
nx, ny, bits)
double xpos, ypos, xlength, ylength;
unsigned char buffer[];
int nx, ny, bits;
Plots a bit-mapped image using grayshades.
Specify position of lower left corner and size (in
inches) of image. buffer is an unsigned character
array with gray shade values (0 - 255) where 0 is
black, 255 is white. bits is number of bits pr
pixel (8, 4, or 1). nx,ny refers to the number of
pixels in image. The rowlength of buffer must be
an integral number of 8/bits. buffer[0] is upper
left corner. E.g. if bits = 4, then buffer[j]/16
gives shade for pixel[2j-1] and buffer[j]%16 (mod
16) gives shade for pixel[2j]. buffer values are
stored as columns, starting at the lower left
corner and ending at the upper right corner. See
the Adobe Systems PostScript Reference Manual for
more details.
void ps_imagefill (x, y, n, image, imagefile, invert,
imagedpi, outline, template, r_rgb, b_rgb)
double x[], y[], x0, y0;
int n, image, invert, imagedpi, outline, template,
f_rgb[3], b_rgb[3];
char imagefile;
Similar to ps_polygon, but fills the area with an
image pattern rather than a color or grayshade. x
and y hold the arrays of n points. 90 predefined
patterns are available (See GMT Appendix E).
image gives the image number (1-90). If set to 0,
imagefile must be the name to the user's image,
which must be stored as a SUN 1-, 8-, or 24-bit
rasterfile. 1-bit images only: (i) If invert is
TRUE (1), the black and white pixels are inter-
changed before plotting. (ii) If template is TRUE
(1), the set pixels are colored using the RGB com-
bination in f_rgb, while the unset are painted
with b_rgb. The unit size of the image is con-
trolled by imagedpi. If set to zero, the image is
plotted at the device resolution. If outline is
TRUE, the current penwidth is used to draw the
polygon outline.
void ps_imagemask (xpos, ypos, xlength, ylength,
buffer, nx, ny, polarity, rgb)
double xpos, ypos, xlength, ylength;
unsigned char buffer[];
int nx, ny, polarity, rgb[3];
Plots a transparent 1-bit image mask using the
given rgb color. Specify position of lower left
corner and size (in inches) of image. buffer is
an unsigned character array with 8 pixels per
byte. nx,ny refers to the number of pixels in
image. The rowlength of buffer must be an
integral number of 8. buffer[0] is upper left
corner. buffer values are stored as columns,
starting at the lower left corner and ending at
the upper right corner. If polarity is 0 then the
bits that are 0 are painted with the rgb color,
else the bits that are 1 are colored. See the
Adobe Systems PostScript Reference Manual for more
details.
void ps_itriangle (xcenter, ycenter, diameter, rgb,
outline)
double xcenter, ycenter, diameter;
int rgb[3], outline;
Plots an inverted and fills it with the specified
color. If outline == 1, the outline will be drawn
using current pen-width and -pattern. The symbol
will fit inside a circle of given diameter.
void ps_line (xarray, yarray, npoints, type, close,
split)
double xarray[], yarray[];
int npoints, type, close, split;
Draw a continuous line from the positions in the
x-y arrays. If close == 1, the first and last
point will automatically be closed by the
PostScript driver. If this is the first segment
in a multi-segment path, set type == 1. To end
the segments and have the line(s) drawn, set type
== 2. Thus, for a single segment, type must be 3.
The line is drawn using the current penwidth.
Only if split is TRUE may ps_line use multiple
strokes to draw lines longer that MAX_PATH.
ps_polygon will call ps_line with split = FALSE
since the path must be continuous. If split is
FALSE and the pathlength exceeds MAX_PATH a warn-
ing will be issued.
unsigned char *ps_loadraster (fp, header, invert, mono-
chrome, template, f_rgb, b_rgb)
FILE *fp;
struct rasterfile *header;
BOOLEAN invert, monochrome, template;
int f_rgb[], b_rgb[];
Reads the image contents of the Sun rasterfile
pointed to by the open filepointer fp. The header
must first be obtained with ps_read_rasheader. If
invert is TRUE then 1-bit images will be bit-
reversed. If monochrome is TRUE then color images
are converted to grayimages using the TV YIQ
translation. If template is TRUE then 1-bit
images will be colorized using the for- and back-
ground colors provided in f_rgb and b_rgb. The
routine can handle 1-, 8-, 24-, or 32-bit files in
old, standard, run-length encoded, or RGB-style
Sun format.
void ps_patch (xarray, yarray, npoints, rgb, outline)
double xarray[], yarray[];
int npoints, rgb[3], outline;
Identical to ps_polygon except polygon must be <
20 points long and there will be no attempt to
shorten the path by discarding unnecessary inter-
mediate points along straight segments. Primarily
used when painting large number of small polygons
and not waste output space.
void ps_pie (xcenter, ycenter, radius, azimuth1,
azimuth2, rgb, outline)
double xcenter, ycenter, radius, azimuth1, azimuth2;
int rgb[3], outline;
Plots a sector of a circle and paints it with the
specified RGB combination. If outline == 1, the
outline will be drawn using current pen-width and
-pattern.
void ps_plot (xabs, yabs, kpen)
double xabs, yabs;
int kpen;
Absolute move (kpen=3) or draw (kpen=2), using
current linewidth.
void ps_plotend (last_page)
int last_page;
Terminates the plotting sequence and closes plot
file (if other than stdout). If last_page == 1,
then a PostScript showpage command is issued,
which initiates the printing process on hardcopy
devices.
void ps_plotinit (plotfile, overlay, mode, xoff, yoff,
xscl, yscl, ncopies, dpi, unit, pagesize, rgb, eps)
char *plotfile;
int overlay, mode, ncopies, dpi, unit;
double xoff, yoff, xscl, yscl;
int pagesize[2], rgb[3]; struct EPS * eps;
Initializes the plotting. If plotfile == NULL (or
""), then output is sent to stdout, else output is
sent to plotfile. overlay should be 1 only if you
plan to append it to some existing PostScript
file. mode contains three flags in the three
lowest bits. The lowest bit controls the plot
orientation and can be 0 (Landscape) or 1 (Por-
trait). The next bit, if set to 1, will re-encode
the fonts to include European accented characters.
The third bit controls the format used to write
PostScript images: 0 means binary, 1 means hexade-
cimal. Most printers needs the latter while some
can handle binary which are 50% smaller and there-
fore execute faster. xoff,yoff are used to move
the origin from the default position in the lower
left corner. xscl,yscl are used to scale the
entire plot (Usually set to 1.0, 1.0). Set
ncopies to get more than 1 copy. dpi sets the
hardcopy resolution in dots pr units. For optimum
plot quality and processing speed, choose dpi to
match the intended plotter resolution. Examples
are 300 for most laserwriters, 2540 for Linotype-
300, and ~85 for SUN screens. When in doubt, use
300. unit can be any of 0 (CM), 1 (INCH), or 2
(M), telling the plot system what units are used
for distance and sizes. Note that, regardless of
choice of unit, dpi is still in dots-pr-inch.
pagesize means the physical width and height of
the plotting media in points, (typically 612 by
792 for Letter or 595 by 842 for A4 laserwriter
plotters. The rgb array holds the color of the
page (usually white = 255,255,255). The EPS
structure is defined in the pslib.h include file
and contains information that will make up the
comments header of a EPS file. Programmers who
plan to call pslib routines should read the com-
ments in pslib.h first. Note that the FORTRAN
binding does not expect this last argument.
void ps_plotr (xrel, yrel, kpen)
double xrel, yrel;
int kpen;
Move (kpen = 3) or draw (kpen = 2) relative to
current point (see ps_plot).
void ps_polygon (xarray, yarray, npoints, rgb, outline)
double xarray[], yarray[];
int npoints, rgb[3], outline;
Creates a colored polygon from the positions in
the x-y arrays. Polygon will automatically be
closed by the PostScript driver. If outline == 0,
no outline is drawn. If outline == 1, the outline
is drawn using current penwidth.
int ps_read_rasheader (fp, header)
FILE *fp;
struct rasterfile *header;
Using the pointer fp to the open file, return the
header structure of the Sun rasterfile. This call
is portable as it operates on the byte level.
Once the header is returned you may obtain the
raster image with ps_loadraster.
void ps_rect (x1, y1, x2, y2, rgb, outline)
double x1, y1, x2, y2;
int red, green, blue, outline;
Plots a colored rectangle. (x1,y1) and (x2,y2) are
any two corners on a diagonal. If outline == 1,
the outline will be drawn using current pen-width
and -pattern.
void ps_rotatetrans (x, y, angle)
double x, y, angle;
Rotates the coordinate system by angle degrees,
then translates origin to (x,y).
void ps_setdash (pattern, offset)
char *pattern;
int offset;
Changes the current dashpattern. The character
string pattern is set to the desired pattern.
E.g., "4 2" and offset = 1 will plot like:
x ---- ---- ----
etc, where x is starting point (The x is not plot-
ted). That is, the line is made up of a repeating
pattern of a 4 units long line and a 2 unit long
gap, starting 1 unit after the x. To reset to
solid line, specify pattern = NULL ("") and offset
= 0. Units are in dpi units.
void ps_setfont (fontnr)
int fontnr;
Changes the current font number to fontnr. The
fonts available are: 0 = Helvetica, 1 = H. Bold,
2 = H. Oblique, 3 = H. Bold-Oblique, 4 = Times, 5
= T. Bold, 6 = T. Italic, 7 = T. Bold Italic, 8 =
Courier, 9 = C. Bold, 10 = C Oblique, 11 = C Bold
Oblique, 12 = Symbol, 13 = AvantGarde-Book, 14 =
A.-BookOblique, 15 = A.-Demi, 16 = A.-DemiOblique,
17 = Bookman-Demi, 18 = B.-DemiItalic, 19 = B.-
Light, 20 = B.-LightItalic, 21 = Helvetica-Narrow,
22 = H-N-Bold, 23 = H-N-Oblique, 24 = H-N-
BoldOblique, 25 = NewCenturySchlbk-Roman, 26 =
N.-Italic, 27 = N.-Bold, 28 = N.-BoldItalic, 29 =
Palatino-Roman, 30 = P.-Italic, 31 = P.-Bold, 32 =
P.-BoldItalic, 33 = ZapfChancery-MediumItalic. If
fontnr is outside this range, it is set to 0.
void ps_setformat (n_decimals)
int n_decimals;
Sets number of decimals to be used when writing
color or gray values. The default setting of 3
gives 1000 choices per red, green, and blue value,
which is more than the 255 choices offered by most
24-bit platforms. Choosing a lower value will
make the output file smaller at the expense of
less color resolution. Still, a value of 2 gives
100 x 100 x 100 = 1 million colors, more than most
eyes can distinguish. For a setting of 1, you
will have 10 nuances per primary color and a total
of 1000 unique combinations.
void ps_setline (linewidth)
int linewidth;
Changes the current linewidth in DPI units. 0
gives thinnest line, but the use of 0 is
implementation-dependent (Works fine on most
laserwriters).
void ps_setpaint (rgb)
int rgb[3];
Changes the current RGB setting for pens and text.
void ps_square (xcenter, ycenter, diameter, rgb, out-
line)
double xcenter, ycenter, diameter;
int rgb[3], outline;
Plots a square and fills it with the specified
color. If outline == 1, the outline will be drawn
using current pen-width and -pattern. The symbol
will fit inside a circle of given diameter.
void ps_star (xcenter, ycenter, diameter, rgb, outline)
double xcenter, ycenter, diameter;
int rgb[3], outline;
Plots a star and fills it with the specified
color. If outline == 1, the outline will be drawn
using current pen-width and -pattern. The symbol
will fit inside a circle of given diameter.
void ps_text (x, y, pointsize, text, angle, justify,
form)
double x, y, angle;
char *text;
int pointsize, justify, form;
The text is plotted starting at (x,y), and will
make an angle with the horizontal. The point
(x,y) maps onto different points of the textstring
by giving various values for justify. It is used
as follows:
9------------10----------- 11
| |
5 6 7
| |
1------------ 2------------ 3
The box represents the textstring. E.g., to plot
a textstring with its center of gravity at (x,y),
you must use justify == 6. If justify is nega-
tive, then all leading and trailing blanks are
stripped before plotting. Certain character
sequences (flags) have special meaning to ps_text.
@~ toggles between current font and the Mathemati-
cal Symbols font. @%no% sets font to no; @%%
resets to starting font. @- turns subscript
on/off, @+ turns superscript on/off, @# turns
small caps on/off, and @\ will make a composite
character of the following two character. Give
fontsize in points (72 points = 1 inch). Nor-
mally, the text is typed using solid characters.
To draw outline characters, set form == 1.
void ps_textbox (x, y, pointsize, text, angle, justify,
outline, dx, dy, rgb)
double x, y, angle, dx, dy;
char *text;
int pointsize, justify, outline, rgb[3];
This function is used in conjugation with ps_text
when a box surrounding the text string is desired.
Taking most of the arguments of ps_text, the user
must also specify the color of the resulting rec-
tangle, and whether its outline should be drawn.
More room between text and rectangle can be
obtained by setting dx and dy accordingly.
void ps_transrotate (x, y, angle)
double x, y, angle;
Translates the origin to (x,y), then rotates the
coordinate system by angle degrees.
void ps_triangle (xcenter, ycenter, diameter, rgb, out-
line)
double xcenter, ycenter, diameter;
int rgb[3], outline;
Plots a triangle and paints it with the specified
RGB combination. If outline == 1, the outline
will be drawn using current pen-width and -pat-
tern. The symbol will fit inside a circle of
given diameter.
void ps_vector (xtail, ytail, xtip, ytip, tailwidth,
headlength, headwidth, headshape, rgb, outline)
double xtail, ytail, xtip, ytip, tailwidth, headlength,
headwidth, headshape;
int rgb[3], outline;
Draws a vector of size and appearance as specified
by the various parameters. headshape can take on
values from 0-1 and specifies how far the inter-
section point between the base of a straight vec-
tor head and the vector line is moved toward the
tip. 0 gives a triangular head, 1.0 gives an
arrow shaped head. If outline == 1, the outline
will be drawn using current penwidth.
void ps_words (x, y, text, n_words, line_space,
par_width, par_just, font, font_size, angle, rgb, jus-
tify, draw_box, x_off, y_off, x_gap, y_gap,
boxpen_width, boxpen_texture, boxpen_offset,
boxpen_rgb, vecpen_width, vecpen_texture,
vecpen_offset, vecpen_rgb, boxfill_rgb)
double x, y, line_space, par_width, angle, x_off,
y_off, x_gap, y_gap;
int n_words, font, font_size, justify, draw_box,
boxpen_width, boxpen_offset;
int boxpen_rgb[3], vecpen_width, vecpen_offset,
vecpen_rgb[3], boxfill_rgb[3];
char **text, *boxpen_texture, *vecpen_texture;
Typesets paragraphs of text. text is an array of
the words to typeset, using the given line-spacing
and paragraph width. The whole text block is
positioned at x, y which is the anchor point on
the box as indicated by justify (see ps_text). The
whole block is then shifted by x_off, y_off.
Inside the box, text is justified left, centered,
right, or justified as governed by par_just
(lcrj). draw_box contains 4 bit flags pertaining
to the surrounding outline box. If on, the first
(lowest) bit draws the box outline. The second
bit fills the box interior. The third bit makes
the outline box have rounded corners (unless
x_gap, y_gap, which specifies the padding between
the text and the box, are zero), while the forth
bit draws a line from the original x, y point to
the shifted position. The escape sequences
described for ps_text applies here, as well as two
additional commands: @;r/g/b; changes the font
color (@;; resets it), and @:size: changes the
font size (@:: resets it).
AUTHOR
Paul Wessel, School of Ocean and Earth Science and Technol-
ogy, 1680 East-West Road, Honolulu, Hawaii 96822, (808)
956-4778, Internet address: wessel@soest.hawaii.edu.
BUGS
Caveat Emptor: The author is not responsible for any disas-
ters, suicide attempts, or ulcers caused by correct or
incorrect use of pslib. If you find bugs, please report
them to the author by electronic mail. Be sure to provide
enough detail so that I can recreate the problem.
RESTRICTIONS
Due to the finite memory of some output devices like Laser-
writers, certain restrictions due to limitations of the
PostScript interpreter apply: For now, the arrays passed to
ps_clipon and ps_polygon must contain less than about 1350
points. Also, the buffer array passed to ps_image must be
able to fit in the available memory. Check the specifica-
tions of the hardcopy device you are using. Note that some
Raster Image Processors (RIPs) do not support direct color
so that the colors you get may not be exactly the ones you
wanted. This is a limitation of the RIP, not the underlying
PostScript code generated by pslib.
REFERENCES
Adobe Systems Inc., 1990, PostScript language reference
manual, 2nd edition, Addison-Wesley, (ISBN 0-201-18127-4).