pslib
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 con
tains 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 posi
tions 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 possi
ble 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.
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
functions 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, stop
val, tickval, label, anotpointsize, side)
double xpos, ypos, length, startval, stopval, tick
val;
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, respectively. labelpointsize = 1.5 * anot
pointsize. A negative tickval will reverse the
sense of positive direction, e.g., to have the
y-axis be positive down.
void ps_circle (xcenter, ycenter, diameter, rgb,
outline)
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;
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 con
sisting 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 col
ors. 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
implemented 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 con
tains 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 cur
rent pen-width and -pattern that fits inside a
circle of given diameter.
void ps_diamond (xcenter, ycenter, diameter, rgb,
outline)
double xcenter, ycenter, diameter;
color. If outline == 1, the outline will be
drawn using current pen-width and -pattern. The
symbol will fit inside a circle of given diame
ter.
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,
outline)
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 diame
ter.
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. Spec
ify position of lower left corner and size (in
inches) of image. buffer is an unsigned charac
ter 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 num
ber 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,
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 interchanged before plotting.
(ii) If template is TRUE (1), the set pixels are
colored using the RGB combination in f_rgb,
while the unset are painted with b_rgb. The unit
size of the image is controlled by imagedpi. If
set to zero, the image is plotted at the device
resolution. If outline is TRUE, the current pen
width 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 inte
gral number of 8. buffer[0] is upper left cor
ner. buffer values are stored as columns, start
ing 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 speci
fied color. If outline == 1, the outline will be
drawn using current pen-width and -pattern. The
symbol will fit inside a circle of given diame
ter.
void ps_line (xarray, yarray, npoints, type, close,
split)
double xarray[], yarray[];
int npoints, type, close, split;
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 pen
width. 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 warning will be issued.
unsigned char *ps_loadraster (fp, header, invert,
monochrome, 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 grayim
ages using the TV YIQ translation. If template
is TRUE then 1-bit images will be colorized
using the for- and background 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, out
line)
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
intermediate 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.
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 (Portrait). 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 hexadecimal. Most printers needs the
latter while some can handle binary which are
50% smaller and therefore 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 resolu
tion 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
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, out
line)
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
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.-Demi
Italic, 19 = B.-Light, 20 = B.-LightItalic, 21 =
Helvetica-Narrow, 22 = H-N-Bold, 23 = H-N-
Oblique, 24 = H-N-BoldOblique, 25 = NewCentu
rySchlbk-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 out
side 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 combi
nations.
void ps_setline (linewidth)
int linewidth;
Changes the current linewidth in DPI units. 0
gives thinnest line, but the use of 0 is imple
mentation-dependent (Works fine on most laser
writers).
void ps_setpaint (rgb)
int rgb[3];
Changes the current RGB setting for pens and
text.
void ps_square (xcenter, ycenter, diameter, rgb,
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 diame
ter.
void ps_star (xcenter, ycenter, diameter, rgb, out
line)
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 diame
ter.
void ps_text (x, y, pointsize, text, angle, jus
tify, 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
negative, 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
Mathematical Symbols font. @%no% sets font to
no; @%% resets to starting font. @- turns sub
script on/off, @+ turns superscript on/off, @#
turns small caps on/off, and @\ will make a com
posite character of the following two character.
Give fontsize in points (72 points = 1 inch).
Normally, the text is typed using solid charac
ters. To draw outline characters, set form ==
1.
void ps_textbox (x, y, pointsize, text, angle, jus
tify, outline, dx, dy, rgb)
double x, y, angle, dx, dy;
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 rectangle, 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,
outline)
double xcenter, ycenter, diameter;
int rgb[3], outline;
Plots a triangle and paints it with the speci
fied RGB combination. If outline == 1, the out
line will be drawn using current pen-width and
-pattern. The symbol will fit inside a circle
of given diameter.
void ps_vector (xtail, ytail, xtip, ytip, tail
width, headlength, headwidth, headshape, rgb, out
line)
double xtail, ytail, xtip, ytip, tailwidth,
headlength, headwidth, headshape;
int rgb[3], outline;
Draws a vector of size and appearance as speci
fied by the various parameters. headshape can
take on values from 0-1 and specifies how far
the intersection point between the base of a
straight vector 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 pen
width.
void ps_words (x, y, text, n_words, line_space,
par_width, par_just, font, font_size, angle, rgb,
justify, draw_box, x_off, y_off, x_gap, y_gap, box
pen_width, boxpen_texture, boxpen_offset, box
pen_rgb, vecpen_width, vecpen_texture, vecpen_off
set, 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];
the words to typeset, using the given line-spac
ing 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, cen
tered, 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 out
line. 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 Tech
nology, 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 dis
asters, 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
Laserwriters, 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 specifications 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).
Man(1) output converted with
man2html