home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------
- * The GMT-system: @(#)pslib.c 2.51 5/3/95
- *
- * Copyright (c) 1991-1995 by P. Wessel and W. H. F. Smith
- * See README file for copying and redistribution conditions.
- *--------------------------------------------------------------------*/
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * pslib is a library of plot functions that create PostScript.
- * All the routines write their output to the same plotting file,
- * which can be dumped to a Postscript output device (laserwriters).
- * pslib can handle and mix text, line-drawings, and bit-map graphics
- * in both black/white and color.
- *
- * pslib conforms to the Encapsulated PostScript Files Specification V 3.0,
- * and pslib documents have successfully been used to make Encapsulated
- * PostScript files on a Macintosh.
- *
- * C considerations:
- * All floating point data are assumed to be of type double.
- * All integer data are assumed to be of type int.
- * All logical data are assumed to be of type int (1 = TRUE, 0 = FALSE).
- *
- * Updated May, 1992 by J. Goff, WHOI to include FORTRAN interfaces
- * Updated July, 1993 by P. Wessel to include more symbosl and binary image output
- * Updated August, 1993 by P. Wessel to only warn about path length problems.
- *
- * FORTRAN considerations:
- * All floating point data are assumed to be DOUBLE PRECISION
- * All integer data are assumed to be INTEGER, i.e. INTEGER*4
- * All LOGICAL/int data are assumed to be of type INTEGER*4 (1 = TRUE, 0 = FALSE).
- *
- * When passing (from FORTRAN to C) a fixed-length character variable which has
- * blanks at the end, append "\0" (null character) after the last non-blank
- * character. This is so that C will know where the character string ends.
- * It is NOT sufficient to pass, for example, "string(1:string_length)".
-
- *
- * List of functions:
- * ps_arc : Draws a circular arc
- * ps_axis : Plots an axis with tickmarks and annotation/label
- * ps_circle : Plots circle and [optionally] fills it
- * ps_clipoff : Restores previous clipping path
- * ps_clipon : Clips plot outside the specified polygon
- * ps_colorimage : Plots a 24-bit 2-D image using the colorimage operator
- * ps_colortiles : Plots a 24-bit 2-D image using tiling
- * ps_command : Writes a given PostScript statement to the plot file
- * ps_comment : Writes a comment statement to the plot file
- * ps_cross : Plots a +
- * ps_diamond : Plots a diamond and [optionally] fills it
- * ps_ellipse : Plots an ellipse and [optionally] fills it
- * ps_hexagon : Plots a hexagon and {optionally] fills it
- * ps_image : Plots a 1-to-8 bit 2-D image using grayshades
- * ps_imagefill : Fills a polygon with a repeating n x n image pattern
- * ps_imagergb : Plots a 24-bit 2-D image using color separations
- * ps_itriangle : Plots an inverted triangle and [optionally] fills it
- * ps_line : Plots a line
- * ps_patch : Special case of ps_polygon: Short polygons only (< 20 points, no path-shortening)
- * ps_pie : Plots a sector of a circle and [optionally] fills it
- * ps_plot : Absolute move to new position (pen up or down)
- * ps_plotend : Close plotfile
- * ps_plotinit : Initialize parameters/open plotfile etc.
- * ps_plotr : Relative move to a new position (pen up or down)
- * ps_polygon : Creates a polygon and optionally fills it
- * ps_rect : Draws a rectangle and [optionally] fills it
- * ps_rotatetrans : Rotates, then translates the coordinate system
- * ps_setdash : Specify pattern for dashed line
- * ps_setfont : Changes current font
- * ps_setformat : Changes # of decimals used in color and gray specs [3]
- * ps_setline : Sets linewidth
- * ps_setpaint : Sets the current r/g/b for fill
- * ps_square : Plots square and [optionally] shades it
- * ps_star : Plots a star and {optionally] fills it
- * ps_text : Plots textstring
- * ps_textbox : Draw a filled box around a textstring
- * ps_transrotate : Translates and rotates the coordinate system
- * ps_triangle : Plots a triangle and [optionally] fills it
- * ps_vector : Draws an vector as specified
- *
- *
- * For information about usage, syntax etc, see the pslib.l manual pages
- *
- * Author: Paul Wessel, Dept. of Geology and Geophysics
- * School of Ocean and Earth Science and Technology
- * 2525 Correa Road, Honolulu, HI 96822
- * wessel@soest.hawaii.edu
- * Date: 3-JAN-1995
- * Version: 2.3a
- *
- * !! Must use -DLIBDIR=\"libdirpath\" when compiling, where libdirpath
- * is where pspatterns are stored
- * ***********************************
- * Note above comment is true only under original unix code provided by
- * Wessell and Smith. The OS/2 version relies on environmental variables
- * [specifically, GMTLIBDIR] to point to the proper data path where the
- * pattens (pspatterns.*) are stored.
- *
- *
- */
-
- #include "pslib_inc.h"
- #include "pslib.h"
-
- /* Define support functions called inside pslib functions */
-
- int get_uppercase();
- char *get_icon();
- char *ps_prepare_text();
- void init_euro_header();
-
- void ps_arc (x, y, radius, az1, az2, status)
- double x, y, radius, az1, az2;
- int status; { /* 1 = set anchor, 2 = set end, 3 = both */
- int ix, iy, ir;
-
- ix = rint (x * ps.scale);
- iy = rint (y * ps.scale);
- ir = rint (radius * ps.scale);
- if (fabs (az1 - az2) > 360.0) az1 = 0.0, az2 = 360.0;
- if (status%2) { /* Beginning of new segment */
- fprintf (ps.fp, "S ");
- ps.npath = 0;
- }
- else
- ps.npath++;
- if (az1 < az2) /* Forward positive arc */
- fprintf (ps.fp, "%d %d %d %lg %lg arc", ix ,iy, ir, az1, az2);
- else /* Negative arc */
- fprintf (ps.fp, "%d %d %d %lg %lg arcn", ix ,iy, ir, az1, az2);
- if (status > 1) fprintf (ps.fp, " S");
- fprintf (ps.fp, "\n");
- }
-
- /* fortran interface */
- int ps_arc_ (x, y, radius, az1, az2, status)
- double *x, *y, *radius, *az1, *az2;
- int *status; {
- ps_arc (*x, *y, *radius, *az1, *az2, *status);
- }
-
- void ps_axis (x, y, length, val0, val1, anotation_int, label, anotpointsize, side)
- double x, y, length, val0, val1, anotation_int;
- int anotpointsize, side;
- char *label; {
- int anot_justify, label_justify, i, j, ndig = 0;
- int left = FALSE;
- double angle, dy, scl, val, anot_off, label_off, xx, sign;
- char text[80], format[20];
-
- if (anotation_int < 0.0) left = TRUE;
- anotation_int = fabs (anotation_int);
- sprintf (text, "%lg\0", anotation_int);
- for (i = 0; text[i] && text[i] != '.'; i++);
- if (text[i]) { /* Found a decimal point */
- for (j = i + 1; text[j]; j++);
- ndig = j - i - 1;
- }
- if (ndig > 0)
- sprintf (format, "%%.%dlf\0", ndig);
- else
- strcpy (format, "%lg");
-
- angle = (side%2) ? 90.0 : 0.0;
- sign = (side < 2) ? -1.0 : 1.0;
- anot_justify = label_justify = (side < 2) ? -10 : -2;
- dy = sign * anotpointsize / ps.points_pr_unit;
-
- fprintf (ps.fp, "\nV %d %d T %lg R\n", (int)rint (x * ps.scale), (int)rint (y * ps.scale), angle);
- ps_plot (0.0, 0.0, 3);
- ps_plot (length, 0.0, 2);
- if ((val1 - val0) == 0.0) {
- fprintf (stderr, "pslib: ERROR: Axis val0 == val1!\n");
- return;
- }
- scl = length / (val1 - val0);
- anot_off = dy;
- label_off = 2.5 * dy;
- dy *= 0.5;
-
- i = 0;
- val = val0;
- while (val <= (val1+SMALL)) {
- i++;
- xx = (val - val0) * scl;
- if (left) xx = length - xx;
- ps_plot (xx, 0.0, 3);
- ps_plot (xx, dy, 2);
- sprintf( text, format, val);
- ps_text (xx, anot_off, anotpointsize, text, 0.0, anot_justify, 0);
- val = val0 + i * anotation_int;
- }
- ps_text (0.5*length, label_off, (int) (anotpointsize*1.5), label, 0.0, label_justify, 0);
- fprintf (ps.fp, "U\n\n");
- }
-
- /* fortran interface */
- int ps_axis_ (x, y, length, val0, val1, anotation_int, label, anotpointsize, side, nlen)
- double *x, *y, *length, *val0, *val1, *anotation_int;
- int *anotpointsize, *side;
- int nlen;
- char *label; {
- ps_axis (*x, *y, *length, *val0, *val1, *anotation_int, label, *anotpointsize, *side);
- }
-
- void ps_circle (x, y, size, r, g, b, outline)
- double x, y, size;
- int r, g, b;
- int outline; {
- int ix, iy, ir;
-
- ix = rint (x * ps.scale);
- iy = rint (y * ps.scale);
- ir = rint (size * ps.scale);
- if (r < 0) /* Outline only */
- fprintf (ps.fp, "N %d %d %d C4\n", ix, iy, ir);
- else if (r != g || g != b) /* Color */
- fprintf (ps.fp, "N %.3lg %.3lg %.3lg %d %d %d C%d\n", r * I_255, g * I_255, b * I_255, ix, iy, ir, outline + 2);
- else /* Grayshade only */
- fprintf (ps.fp, "N %.3lg %d %d %d C%d\n", r * I_255, ix, iy, ir, outline);
- ps.npath = 0;
- }
-
- /* fortran interface */
- int ps_circle_ (x, y, size, r, g, b, outline)
- double *x, *y, *size;
- int *r, *g, *b;
- int *outline; {
- ps_circle (*x, *y, *size, *r, *g, *b, *outline);
- }
-
- void ps_clipoff () {
- fprintf (ps.fp, "\nS U\n%%Clipping is currently OFF\n");
- ps.npath = ps.clip_path_length = 0;
- }
-
- /* fortran interface */
- int ps_clipoff_ () {
- ps_clipoff ();
- }
-
- void ps_clipon (x, y, n, r, g, b, flag)
- double x[], y[];
- int n; /* Path length */
- int r, g, b; /* Optional paint (-1 to avoid paint) */
- int flag; { /* combo of 1 | 2. 1 = Start, 2 = end */
- /* Any plotting outside the path defined by x,y will be clipped.
- use clipoff to restore the original clipping path. */
-
- int used;
- char move[7];
-
- if (flag & 1) { /* First segment in (possibly multi-segmented) clip-path */
- strcpy (move, "M");
- fprintf (ps.fp, "\n%%Start of clip path\nS V\n");
- ps.npath = 0;
- }
- else
- strcpy (move, "moveto");
-
- used = 0;
- if (n > 0) {
- ps.ix = rint (x[0]*ps.scale);
- ps.iy = rint (y[0]*ps.scale);
- ps.npath++;
- used++;
- fprintf (ps.fp, "%d %d %s\n", ps.ix, ps.iy, move);
- used += ps_line (&x[1], &y[1], n-1, 0, TRUE, FALSE);
- }
- ps.clip_path_length += used;
- ps.max_path_length = MAX (ps.clip_path_length, ps.max_path_length);
-
- if (flag & 2) { /* End path and [optionally] fill */
- if (r >= 0 && (r != g || g != b)) /* color*/
- fprintf (ps.fp, "V %.3lg %.3lg %.3lg C eofill U ", r * I_255, g * I_255, b * I_255);
- else if (r >= 0)
- fprintf (ps.fp, "V %.3lg A eofill U ", r * I_255);
- if (flag & 4)
- fprintf (ps.fp, "eoclip\n%%End of clip path. Clipping is currently ON\n");
- else
- fprintf (ps.fp, "eoclip N\n%%End of clip path. Clipping is currently ON\n");
- ps.npath = 0;
- }
- }
-
- /* fortran interface */
- int ps_clipon_ (x, y, n, r, g, b, flag)
- double x[], y[];
- int *n, *r, *g, *b, *flag; {
- ps_clipon (x, y, *n, *r, *g, *b, *flag);
- }
-
- void ps_colorimage (x, y, xsize, ysize, buffer, nx, ny)
- double x, y, xsize, ysize;
- unsigned char *buffer;
- int nx, ny; {
- /* Plots a color bitmapped image. Each pixel is described by
- * 3 hexadecimal numbers, each may take on values from
- * 00(0) to FF(255). buffer stores the colroinfo in
- * r g b r g b r g b format. Kosher Adobe operator.
- */
- if (ps.hex_image)
- ps_colorimage_hex (x, y, xsize, ysize, buffer, nx, ny);
- else
- ps_colorimage_bin (x, y, xsize, ysize, buffer, nx, ny);
- }
-
- int ps_colorimage_hex (x, y, xsize, ysize, buffer, nx, ny)
- double x, y, xsize, ysize;
- unsigned char *buffer;
- int nx, ny; {
- /* Writes output image using hex format */
- char hex[16], pixel[61];
- int ix, iy, lx, ly, mx, i, j, kk, ij;
-
- pixel[60] = 0;
- hex[0] = '0'; hex[1] = '1'; hex[2] = '2'; hex[3] = '3';
- hex[4] = '4'; hex[5] = '5'; hex[6] = '6'; hex[7] = '7';
- hex[8] = '8'; hex[9] = '9'; hex[10] = 'A'; hex[11] = 'B';
- hex[12] = 'C'; hex[13] = 'D'; hex[14] = 'E'; hex[15] = 'F';
-
- ix = rint (x * ps.scale);
- iy = rint (y * ps.scale);
- lx = rint (xsize * ps.scale);
- ly = rint (ysize * ps.scale);
- mx = 3 * nx;
- fprintf (ps.fp, "\n%% Start of hex Adobe colorimage\n");
- fprintf (ps.fp, "V N %d %d T %d %d scale\n", ix, iy, lx, ly);
- fprintf (ps.fp, "%d string /pstr exch def\n", mx);
- fprintf (ps.fp, "%d %d 8 [%d 0 0 %d 0 %d] {currentfile pstr readhexstring pop} false 3 colorimage\n",
- nx, ny, nx, -ny, ny);
- kk = 0;
- for (j = ij = 0; j < ny; j++) {
- for (i = 0; i < nx; i++) {
- pixel[kk++] = hex[buffer[ij] / 16];
- pixel[kk++] = hex[buffer[ij++] % 16];
- pixel[kk++] = hex[buffer[ij] / 16];
- pixel[kk++] = hex[buffer[ij++] % 16];
- pixel[kk++] = hex[buffer[ij] / 16];
- pixel[kk++] = hex[buffer[ij++] % 16];
- if (kk == 60) {
- fprintf (ps.fp, "%s\n", pixel);
- kk = 0;
- }
- }
- }
- if (kk > 0) {
- pixel[kk] = 0;
- fprintf (ps.fp, "%s\n", pixel);
- }
- fprintf (ps.fp, "U\n%% End of colorimage\n\n");
- }
-
- int ps_colorimage_bin (x, y, xsize, ysize, buffer, nx, ny)
- double x, y, xsize, ysize;
- unsigned char *buffer;
- int nx, ny; {
- /* Writes output image using bin format */
-
- int ix, iy, lx, ly, mx;
-
- ix = rint (x * ps.scale);
- iy = rint (y * ps.scale);
- lx = rint (xsize * ps.scale);
- ly = rint (ysize * ps.scale);
- mx = 3 * nx;
- fprintf (ps.fp, "\n%% Start of binary Adobe colorimage\n");
- fprintf (ps.fp, "V N %d %d T %d %d scale\n", ix, iy, lx, ly);
- fprintf (ps.fp, "%d string /pstr exch def\n", mx);
- fprintf (ps.fp, "%d %d 8 [%d 0 0 %d 0 %d] {currentfile pstr readstring pop} false 3 colorimage\n",
- nx, ny, nx, -ny, ny);
- fwrite ((char *)buffer, sizeof (unsigned char), mx * ny, ps.fp);
- fprintf (ps.fp, "\nU\n%% End of colorimage\n\n");
- }
-
- /* fortran interface */
- int ps_colorimage_ (x, y, xsize, ysize, buffer, nx, ny, nlen)
- double *x, *y, *xsize, *ysize;
- unsigned char *buffer;
- int nlen;
- int *nx, *ny; {
- ps_colorimage (*x, *y, *xsize, *ysize, buffer, *nx, *ny);
- }
-
- void ps_colortiles (x0, y0, dx, dy, image, nx, ny)
- double x0, y0; /* Lower left corner in inches */
- double dx, dy; /* Size of cell in inches */
- unsigned char *image; /* color image */
- int nx, ny; { /* image size */
- int i, j, k, r, g, b;
- double x1, x2, y1, y2, noise, noise2;
-
- noise = 2.0 / ps.scale;
- noise2 = 2.0 * noise;
- dx /= nx;
- dy /= ny;
-
- ps_transrotate (x0, y0, 0.0);
- y2 = (ny - 0.5) * dy + 0.5 * noise;
- for (j = k = 0; j < ny; j++) {
- y1 = (ny - j - 1.5) * dy - 0.5 * noise;
- x1 = -0.5 * (dx + noise);
- for (i = 0; i < nx; i++) {
- x2 = (i + 0.5) * dx + noise;
- r = image[k++];
- g = image[k++];
- b = image[k++];
- ps_rect (x1, y1, x2, y2, r, g, b, FALSE);
- x1 = x2 - noise2;
- }
- y2 = y1 + noise2;
- }
- ps_rotatetrans (-x0, -y0, 0.0);
- }
-
- /* fortran interface */
- int ps_colortiles_ (x0, y0, dx, dy, image, nx, ny, nlen)
- double *x0, *y0;
- double *dx, *dy;
- unsigned char *image;
- int nlen;
- int *nx, *ny; {
- ps_colortiles (*x0, *y0, *dx, *dy, image, *nx, *ny);
- }
-
- void ps_command (text)
- char *text; {
- fprintf (ps.fp, "%s\n", text);
- }
-
- /* fortran interface */
- int ps_command_ (text, nlen)
- int nlen;
- char *text; {
- ps_command (text);
- }
-
- void ps_comment (text)
- char *text; {
- fprintf (ps.fp, "%% %s\n", text);
- }
-
- /* fortran interface */
- int ps_comment_ (text, nlen)
- int nlen;
- char *text; {
- ps_comment (text);
- }
-
- void ps_cross (x, y, size)
- double x, y, size; {
- fprintf (ps.fp, "%d %d %d X\n", (int) rint (size * ps.scale), (int) rint ((x - 0.5 * size) * ps.scale), (int ) rint (y * ps.scale));
- ps.npath = 0;
- }
-
- /* fortran interface */
- int ps_cross_ (x, y, size)
- double *x, *y, *size; {
- ps_cross (*x, *y, *size);
- }
-
- void ps_diamond (x, y, side, r, g, b, outline)
- double x, y, side;
- int r, g, b;
- int outline; { /* see circle */
- int ix, iy, ds;
-
- side *= (1.0/M_SQRT2);
- ds = rint (side * ps.scale);
- ix = rint (x * ps.scale);
- iy = rint ((y - side) * ps.scale);
- if (r < 0) /* Outline only */
- fprintf (ps.fp, "%d %d %d D4\n", ds, ix, iy);
- else if (r != g || g != b) /* color */
- fprintf (ps.fp, "%.3lg %.3lg %.3lg %d %d %d D%d\n", r * I_255, g * I_255, b * I_255, ds, ix, iy, outline+2);
- else /* Grayshade only */
- fprintf (ps.fp, "%.3lg %d %d %d D%d\n", r * I_255, ds, ix, iy, outline);
- ps.npath = 0;
- }
-
- /* fortran interface */
- int ps_diamond_ (x, y, side, r, g, b, outline)
- double *x, *y, *side;
- int *r, *g, *b;
- int *outline; {
- ps_diamond (*x, *y, *side, *r, *g, *b, *outline);
- }
-
- void ps_star (x, y, side, r, g, b, outline)
- double x, y, side;
- int r, g, b;
- int outline; { /* see circle */
- int ix, iy, ds;
-
- ds = rint (side * ps.scale);
- ix = rint (x * ps.scale);
- iy = rint (y * ps.scale);
- if (r < 0) /* Outline only */
- fprintf (ps.fp, "%d %d %d E4\n", ds, ix, iy);
- else if (r != g || g != b) /* color */
- fprintf (ps.fp, "%.3lg %.3lg %.3lg %d %d %d E%d\n", r * I_255, g * I_255, b * I_255, ds, ix, iy, outline+2);
- else /* Grayshade only */
- fprintf (ps.fp, "%.3lg %d %d %d E%d\n", r * I_255, ds, ix, iy, outline);
- ps.npath = 0;
- }
-
- /* fortran interface */
- int ps_star_ (x, y, side, r, g, b, outline)
- double *x, *y, *side;
- int *r, *g, *b;
- int *outline; {
- ps_star (*x, *y, *side, *r, *g, *b, *outline);
- }
-
- void ps_hexagon (x, y, side, r, g, b, outline)
- double x, y, side;
- int r, g, b;
- int outline; { /* see circle */
- int ix, iy, ds;
-
- ds = rint (side * ps.scale);
- ix = rint (x * ps.scale);
- iy = rint (y * ps.scale);
- if (r < 0) /* Outline only */
- fprintf (ps.fp, "%d %d %d H4\n", ds, ix, iy);
- else if (r != g || g != b) /* color */
- fprintf (ps.fp, "%.3lg %.3lg %.3lg %d %d %d H%d\n", r * I_255, g * I_255, b * I_255, ds, ix, iy, outline+2);
- else /* Grayshade only */
- fprintf (ps.fp, "%.3lg %d %d %d H%d\n", r * I_255, ds, ix, iy, outline);
- ps.npath = 0;
- }
-
- /* fortran interface */
- int ps_hexagon_ (x, y, side, r, g, b, outline)
- double *x, *y, *side;
- int *r, *g, *b;
- int *outline; {
- ps_hexagon (*x, *y, *side, *r, *g, *b, *outline);
- }
-
- void ps_ellipse (x, y, angle, major, minor, r, g, b, outline)
- double x, y, angle, major, minor;
- int r, g, b, outline; {
- int ir;
- double aspect;
-
- /* Feature: Pen thickness also affected by ascpect ratio */
-
- fprintf (ps.fp, "V %d %d T", (int) rint (x * ps.scale), (int) rint (y * ps.scale));
- if (angle != 0.0) fprintf (ps.fp, " %lg R", angle);
- aspect = minor / major;
- fprintf (ps.fp, " 1 %lg scale\n", aspect);
- ir = rint (major * ps.scale);
- if (r < 0) /* Outline only */
- fprintf (ps.fp, " 0 0 %d C4 U\n", ir);
- else if (r != g || g != b) /* color */
- fprintf (ps.fp, " %.3lg %.3lg %.3lg 0 0 %d C%d U\n", r * I_255, g * I_255, b * I_255, ir, outline + 2);
- else /* Grayshade only */
- fprintf (ps.fp, " %.3lg 0 0 %d C%d U\n", r * I_255, ir, outline);
- }
-
- /* fortran interface */
- int ps_ellipse_ (x, y, angle, major, minor, r, g, b, outline)
- double *x, *y, *angle, *major, *minor;
- int *r, *g, *b, *outline; {
- ps_ellipse (*x, *y, *angle, *major, *minor, *r, *g, *b, *outline);
- }
-
- void ps_image (x, y, xsize, ysize, buffer, nx, ny, nbits)
- double x, y, xsize, ysize;
- unsigned char *buffer;
- int nx, ny, nbits; {
- /* Plots a bitmapped image. Each pixel is described by
- * a hexadecimal number, which may take on values from
- * 00(0) to FF(255).
- * nbits is no of bits/pixel. Can be 8,4, or 1.
- * Eg. if 1 is used, the each element of buffer provides
- * shade info for 8 pixels, going from left to right.
- * Note that nx refers to number of buffer values, not pixels.
- * nx must be an integral of 8/nbits.
- */
- if (ps.hex_image)
- ps_image_hex (x, y, xsize, ysize, buffer, nx, ny, nbits);
- else
- ps_image_bin (x, y, xsize, ysize, buffer, nx, ny, nbits);
- }
-
- int ps_image_hex (x, y, xsize, ysize, buffer, nx, ny, nbits)
- double x, y, xsize, ysize;
- unsigned char *buffer;
- int nx, ny, nbits; {
- /* Write output image using hex notation */
-
- char hex[16], pixel[80];
- int ix, iy, lx, ly, mx, i, j, kk, jj, width;
-
- hex[0] = '0'; hex[1] = '1'; hex[2] = '2'; hex[3] = '3';
- hex[4] = '4'; hex[5] = '5'; hex[6] = '6'; hex[7] = '7';
- hex[8] = '8'; hex[9] = '9'; hex[10] = 'A'; hex[11] = 'B';
- hex[12] = 'C'; hex[13] = 'D'; hex[14] = 'E'; hex[15] = 'F';
-
- ix = rint (x * ps.scale);
- iy = rint (y * ps.scale);
- lx = rint (xsize * ps.scale);
- ly = rint (ysize * ps.scale);
- mx = nx * 8 / nbits;
- fprintf (ps.fp, "\n%% Start of hex monochrome image\n");
- fprintf (ps.fp, "V N %d %d T %d %d scale\n", ix, iy, lx, ly);
- fprintf (ps.fp, "%d %d 8 div mul ceiling cvi string /pstr exch def\n", mx, nbits);
- fprintf (ps.fp, "%d %d %d [%d 0 0 %d 0 %d] {currentfile pstr readhexstring pop} image\n",
- mx, ny, nbits, mx, -ny, ny);
-
- width = (nx > 40) ? 80 : 2 * nx;
- kk = 0;
- for (j = jj = 0; j < ny; j++) {
- for (i = 0; i < nx; i++, jj++) {
- pixel[kk++] = hex[buffer[jj]/16];
- pixel[kk++] = hex[buffer[jj]%16];
- if (kk == width) {
- for (kk = 0; kk < width; kk++) putc (pixel[kk], ps.fp);
- putc ('\n', ps.fp);
- kk = 0;
- }
- }
- }
- if (kk > 0) {
- for (i = 0; i < kk; i++) putc (pixel[i], ps.fp);
- putc ('\n', ps.fp);
- }
- fprintf (ps.fp, "U\n%% End of image\n\n");
- }
-
- int ps_image_bin (x, y, xsize, ysize, buffer, nx, ny, nbits)
- double x, y, xsize, ysize;
- unsigned char *buffer;
- int nx, ny, nbits; {
- /* Write output image using bin notation */
- int ix, iy, lx, ly, mx;
-
- ix = rint (x * ps.scale);
- iy = rint (y * ps.scale);
- lx = rint (xsize * ps.scale);
- ly = rint (ysize * ps.scale);
- mx = nx * 8 / nbits;
- fprintf (ps.fp, "\n%% Start of binary monochrome image\n");
- fprintf (ps.fp, "V N %d %d T %d %d scale\n", ix, iy, lx, ly);
- fprintf (ps.fp, "%d %d 8 div mul ceiling cvi string /pstr exch def\n", mx, nbits);
- fprintf (ps.fp, "%d %d %d [%d 0 0 %d 0 %d] {currentfile pstr readstring pop} image\n",
- mx, ny, nbits, mx, -ny, ny);
-
- fwrite ((char *)buffer, sizeof (unsigned char), nx * ny, ps.fp);
- fprintf (ps.fp, "\nU\n%% End of image\n\n");
- }
-
- /* fortran interface */
- int ps_image_ (x, y, xsize, ysize, buffer, nx, ny, nbits, nlen)
- double *x, *y, *xsize, *ysize;
- unsigned char *buffer;
- int nlen;
- int *nx, *ny, *nbits; {
- ps_image (*x, *y, *xsize, *ysize, buffer, *nx, *ny, *nbits);
- }
-
- void ps_imagefill (x, y, n, image_no, imagefile, invert, image_size, outline)
- double x[], y[];
- double image_size; /* Size of image on page in inches */
- int n; /* No of points in path */
- int image_no; /* no of image (1-32) or user (0) */
- char *imagefile; /* Name of image file if image == 0 */
- int invert; /* If invert == TRUE we interchange black and white pixels */
- int outline; { /* TRUE will draw outline, -1 means clippath already in place */
- int i, j, ix, iy, no, n_times = 0;
- char op[15];
- double xx, yy, xmin, xmax, ymin, ymax;
-
- image_no--; /* Frome 1-32 to 0-31 */
- if (image_no < 0) image_no = 32; /* Usersupplied image */
- if (ps_pattern_status[image_no][invert] != 1) {
- no = (image_no == 32) ? -1 : image_no+1;
- ps_imagefill_init (no, imagefile, invert, image_size);
- }
-
- ps_comment ("\n%Start of user imagefill pattern");
- if (invert)
- sprintf (op, "fillimage%di\0", image_no);
- else
- sprintf (op, "fillimage%d\0", image_no);
-
- /* Print out clip-path */
-
- if (outline >= 0) ps_clipon (x, y, n, -1, -1, -1, 3);
-
- /* Find extreme bounds for area */
-
- xmin = xmax = x[0];
- ymin = ymax = y[0];
- for (i = 1; i < n; i++) {
- xmin = MIN (xmin, x[i]);
- ymin = MIN (ymin, y[i]);
- xmax = MAX (xmax, x[i]);
- ymax = MAX (ymax, y[i]);
- }
-
- if (image_size <= 0.0) image_size = 64.0 / ps.scale; /* Use device resolution */
-
- for (j = (int) floor (ymin / image_size); j <= (int) ceil (ymax / image_size); j++) {
- yy = j * image_size;
- for (i = (int) floor (xmin / image_size); i <= (int) ceil (xmax / image_size); i++) {
- xx = i * image_size;
- ix = rint (xx * ps.scale);
- iy = rint (yy * ps.scale);
- fprintf (ps.fp, "%d %d", ix, iy);
- n_times++;
- (n_times%5) ? putc (' ', ps.fp) : putc ('\n', ps.fp);
- /* Prevent stack from getting too full by flushing every 200 times */
- if (!(n_times%200)) { fprintf (ps.fp, "200 {%s} repeat\n", op); n_times = 0;}
- }
- }
- if (n_times%5) putc ('\n', ps.fp);
- fprintf (ps.fp, "%d {%s} repeat\n", n_times, op);
- if (outline > 0) fprintf (ps.fp, "clippath S\n");
- ps_clipoff ();
- ps_comment ("End of user imagefill pattern\n");
- }
-
- void ps_imagefill_init (image_no, imagefile, invert, image_size)
- double image_size; /* Size of image on page in inches */
- int image_no; /* no of image (1-32) or user (0) */
- int invert; /* If invert == TRUE we interchange black and white pixels */
- char *imagefile; { /* Name of image file if image == 0 */
- char *gmt_data_path; /* variable pointing to directory for patterns */
- int i, nx, ny, dx, dump = FALSE;
- char *string, tmp[65], name[10], file[512];
- /* Added for OS/2 [but works under unix] */
- gmt_data_path = getenv (GMTDATAPATH); /* GMTDATAPATH defined in "gmt_os2.h" */
-
- if (image_size <= 0.0) { /* Use device resolution */
- dx = 64;
- image_size = 64.0 / ps.scale;
- }
- else
- dx = rint (image_size * ps.scale);
-
- image_no--; /* Frome 1-32 to 0-31 */
- if (image_no < 0) image_no = 32;
- if (ps_pattern_status[image_no][invert]) return; /* Already done this */
-
- if (image_no >= 0 && image_no < N_PATTERNS && ps_pattern_status[image_no][invert] == 0) {
- sprintf (file, "%s/ps_pattern.%d\0", gmt_data_path, image_no);
- /* -----------Original GMT code; modified for OS/2----------- */
- /* sprintf (file, "%s/ps_pattern.%d\0", LIBDIR, image_no); */
- string = get_icon (file, &nx, &ny, invert);
- }
- else if (image_no == 32 && ps_pattern_status[32][invert] == 0)
- string = get_icon (imagefile, &nx, &ny, invert);
- else if (ps_pattern_status[image_no][invert] == 1) {
- nx = ps_pattern_nx[image_no][invert];
- ny = ps_pattern_ny[image_no][invert];
- dx = ps_pattern_dx[image_no][invert];
- }
- ps_comment ("\n%Start of user imagefill pattern definition");
- if (invert)
- sprintf (name, "image%di\0", image_no);
- else
- sprintf (name, "image%d\0", image_no);
- if (ps_pattern_status[image_no][invert] == 0) {
- fprintf (ps.fp, "/%s <\n", name);
- ps_pattern_status[image_no][invert] = 1;
- ps_pattern_nx[image_no][invert] = nx;
- ps_pattern_ny[image_no][invert] = ny;
- ps_pattern_dx[image_no][invert] = dx;
- dump = TRUE;
- }
- if (dump) {
- for (i = 0; i < nx * ny / 256; i++) {
- strncpy (tmp, &string[i*64], 64);
- tmp[64] = 0;
- fprintf (ps.fp, "\t%s\n", tmp);
- }
- fprintf (ps.fp, "> def\n");
- }
- fprintf (ps.fp, "/fill%s { V T %d dup scale %d %d 1 [%d 0 0 %d 0 %d] {%s} image U} def\n", name, dx, nx, ny, nx, -ny, ny, name);
- if (dump) free (string);
-
- ps_comment ("End of user imagefill pattern definition\n");
- }
-
- void ps_imagefill_cleanup () {
- int image_no;
-
- for (image_no = 0; image_no < 32; image_no++) {
- if (ps_pattern_status[image_no][0]) {
- fprintf (ps.fp, "currentdict /image%d undef\n", image_no);
- fprintf (ps.fp, "currentdict /fillimage%d undef\n", image_no);
- }
- if (ps_pattern_status[image_no][1]) {
- fprintf (ps.fp, "currentdict /image%di undef\n", image_no);
- fprintf (ps.fp, "currentdict /fillimage%di undef\n", image_no);
- }
- }
- }
-
- /* fortran interface */
- int ps_imagefill_ (x, y, n, image_no, imagefile, invert, image_size, outline, nlen)
- double x[], y[];
- double *image_size;
- int *n;
- int *image_no;
- int *invert;
- char *imagefile;
- int nlen;
- int *outline; {
- ps_imagefill (x, y, *n, *image_no, imagefile, *invert, *image_size, *outline);
- }
-
- void ps_imagergb (x, y, xsize, ysize, buffer, nx, ny)
- double x, y, xsize, ysize;
- unsigned char *buffer;
- int nx, ny; {
- /* Plots a 24bit bitmapped image using three calls to image
- called rimage, gimage, bimage. These will be defined and
- undefined when psto24 is run.
- * Temporary version untill colorimage is defined
- */
-
- if (ps.hex_image)
- ps_imagergb_hex (x, y, xsize, ysize, buffer, nx, ny);
- else
- ps_imagergb_bin (x, y, xsize, ysize, buffer, nx, ny);
- }
-
- int ps_imagergb_hex (x, y, xsize, ysize, buffer, nx, ny)
- double x, y, xsize, ysize;
- unsigned char *buffer;
- int nx, ny; {
- /* Writes output image using hex notation */
-
- char hex[16], pixel[80];
- int ix, iy, lx, ly, i, j, kk, jj, color;
-
- hex[0] = '0'; hex[1] = '1'; hex[2] = '2'; hex[3] = '3';
- hex[4] = '4'; hex[5] = '5'; hex[6] = '6'; hex[7] = '7';
- hex[8] = '8'; hex[9] = '9'; hex[10] = 'A'; hex[11] = 'B';
- hex[12] = 'C'; hex[13] = 'D'; hex[14] = 'E'; hex[15] = 'F';
- ix = rint (x * ps.scale);
- iy = rint (y * ps.scale);
- lx = rint (xsize * ps.scale);
- ly = rint (ysize * ps.scale);
- fprintf (ps.fp, "\n%% Start of hex psto24 rgb colorimage\n");
- fprintf (ps.fp, "V N %d %d T %d %d scale\n", ix, iy, lx, ly);
- fprintf (ps.fp, "%d string /pstr exch def\n", nx);
-
- for (color = jj = 0; color < 3; color++) {
- fprintf (ps.fp, "psto24pass %d eq\n", color);
- fprintf (ps.fp, "{%d %d 8 [%d 0 0 %d 0 %d] {currentfile pstr readhexstring pop} image}\n",
- nx, ny, nx, -ny, ny);
- fprintf (ps.fp, "{%d {currentfile pstr readhexstring pop pop} repeat}\n", ny);
- fprintf (ps.fp, "ifelse\n");
- kk = 0;
- for (j = 0; j < ny; j++) {
- for (i = 0; i < nx; i++, jj++) {
- pixel[kk++] = hex[buffer[jj]/16];
- pixel[kk++] = hex[buffer[jj]%16];
- if (kk == 80) {
- for (kk = 0; kk < 80; kk++) putc (pixel[kk], ps.fp);
- putc ('\n', ps.fp);
- kk = 0;
- }
- }
- }
- if (kk > 0) {
- for (i = 0; i < kk; i++) putc (pixel[i], ps.fp);
- putc ('\n', ps.fp);
- }
- }
- fprintf (ps.fp, "U\n%% End of imagergb\n\n");
- }
-
- int ps_imagergb_bin (x, y, xsize, ysize, buffer, nx, ny)
- double x, y, xsize, ysize;
- unsigned char *buffer;
- int nx, ny; {
- /* Writes output image using bin notation */
-
- int ix, iy, lx, ly, color;
-
- ix = rint (x * ps.scale);
- iy = rint (y * ps.scale);
- lx = rint (xsize * ps.scale);
- ly = rint (ysize * ps.scale);
- fprintf (ps.fp, "\n%% Start of binary psto24 colorimage\n");
- fprintf (ps.fp, "V N %d %d T %d %d scale\n", ix, iy, lx, ly);
- fprintf (ps.fp, "%d string /pstr exch def\n", nx);
-
- for (color = 0; color < 3; color++) {
- fprintf (ps.fp, "psto24pass %d eq\n", color);
- fprintf (ps.fp, "{%d %d 8 [%d 0 0 %d 0 %d] {currentfile pstr readstring pop} image}\n",
- nx, ny, nx, -ny, ny);
- fprintf (ps.fp, "{%d {currentfile pstr readhexstring pop pop} repeat}\n", ny);
- fprintf (ps.fp, "ifelse\n");
- fwrite ((char *)buffer, sizeof (unsigned char), nx * ny, ps.fp);
- }
- fprintf (ps.fp, "\nU\n%% End of imagergb\n\n");
- }
-
- /* fortran interface */
- int ps_imagergb_ (x, y, xsize, ysize, buffer, nx, ny, nlen)
- double *x, *y, *xsize, *ysize;
- unsigned char *buffer;
- int nlen;
- int *nx, *ny; {
- ps_imagergb (*x, *y, *xsize, *ysize, buffer, *nx, *ny);
- }
-
- int ps_line (x, y, n, type, close, split)
- double *x, *y;
- int n, type; /* type: 1 means new anchor point, 2 means stroke line, 3 = both */
- int close; /* TRUE if a closed polygon */
- int split; { /* TRUE if we can split line segment into several sections */
- int i, *ix, *iy, trim = FALSE;
- char move = 'M';
-
- /* First remove unneccessary points that have zero curvature */
-
- ix = (int *) malloc ((unsigned) (n * sizeof (int)));
- iy = (int *) malloc ((unsigned) (n * sizeof (int)));
-
- if ((n = ps_shorten_path (x, y, n, ix, iy)) < 2) {
- free ((char *)ix);
- free ((char *)iy);
- return (0);
- }
-
- if (close && ix[0] == ix[n-1] && iy[0] == iy[n-1]) {
- trim = TRUE;
- n--;
- }
-
- if (type < 0) { /* Do not stroke before moveto */
- type = -type;
- move = 'm';
- }
-
- if (type%2) {
- fprintf (ps.fp, "%d %d %c\n", ix[0], iy[0], move);
- ps.npath = 1;
- }
- else
- fprintf (ps.fp, "%d %d D\n", ix[0] - ps.ix, iy[0] - ps.iy);
- ps.ix = ix[0];
- ps.iy = iy[0];
-
- if (!split) ps.max_path_length = MAX ((n + ps.clip_path_length), ps.max_path_length);
-
- for (i = 1; i < n; i++) {
- fprintf (ps.fp, "%d %d D\n", ix[i] - ps.ix, iy[i] - ps.iy);
- ps.ix = ix[i];
- ps.iy = iy[i];
- ps.npath++;
- if ((ps.npath + ps.clip_path_length) > ps.v1_path_length_limit && split) {
- fprintf (ps.fp, "S %d %d M\n", ps.ix, ps.iy);
- ps.npath = 1;
- close = FALSE;
- if (trim) { /* Restore the duplicate point since close no longer is TRUE */
- n++;
- trim = FALSE;
- }
- }
- }
- if (close) fprintf (ps.fp, "P"); /* Close the path */
- if (type > 1) {
- fprintf (ps.fp, " S\n"); /* Stroke the path */
- ps.npath = 0;
- }
- else if (close)
- fprintf (ps.fp, "\n");
-
- free ((char *)ix);
- free ((char *)iy);
-
- return (n);
- }
-
- /* fortran interface */
- int ps_line_ (x, y, n, type, close, split)
- double x[], y[];
- int *n, *type;
- int *close, *split; {
- ps_line (x, y, *n, *type, *close, *split);
- }
-
- int ps_shorten_path (x, y, n, ix, iy)
- double x[], y[];
- int n;
- int ix[], iy[]; {
- double old_slope, new_slope, dx, dy, old_dir, new_dir;
- int i, j, k, *xx, *yy, fixed;
-
- if (n < 2) return (0);
-
- xx = (int *) malloc ( (unsigned) (n * sizeof (int)));
- yy = (int *) malloc ( (unsigned) (n * sizeof (int)));
-
- xx[0] = rint (x[0] * ps.scale);
- yy[0] = rint (y[0] * ps.scale);
-
- for (i = j = 1; i < n; i++) {
- xx[j] = rint (x[i] * ps.scale);
- yy[j] = rint (y[i] * ps.scale);
- if (xx[j] != xx[j-1] || yy[j] != yy[j-1]) j++;
- }
- n = j;
-
- if (n < 2) {
- free ((char *)xx);
- free ((char *)yy);
- return (0);
- }
-
- ix[0] = xx[0]; iy[0] = yy[0]; k = 1;
-
- dx = xx[1] - xx[0];
- dy = yy[1] - yy[0];
- fixed = (dx == 0.0 && dy == 0.0);
- old_slope = (fixed) ? 1.01e100 : ((dx == 0) ? copysign (1.0e100, dy) : dy / dx);
- old_dir = 1;
-
- for (i = 1; i < n-1; i++) {
- dx = xx[i+1] - xx[i];
- dy = yy[i+1] - yy[i];
- fixed = (dx == 0.0 && dy == 0.0);
- new_slope = (fixed) ? 1.01e100 : ((dx == 0) ? copysign (1.0e100, dy) : dy / dx);
- if (fixed) continue; /* Didnt move */
-
- new_dir = (dx >= 0.0) ? 1 : -1;
- if (new_slope != old_slope || new_dir != old_dir) {
- ix[k] = xx[i];
- iy[k] = yy[i];
- k++;
- old_slope = new_slope;
- old_dir = new_dir;
- }
- }
- dx = xx[n-1] - xx[n-2];
- dy = yy[n-1] - yy[n-2];
- fixed = (dx == 0.0 && dy == 0.0 && (k > 1 && ix[k-1] == xx[n-1] && iy[k-1] == yy[n-1])); /* Didnt move */
- if (!fixed) {
- ix[k] = xx[n-1];
- iy[k] = yy[n-1];
- k++;
- }
-
- free ((char *)xx);
- free ((char *)yy);
-
- return (k);
- }
-
- /* fortran interface */
- int ps_shorten_path_ (x, y, n, ix, iy)
- double x[], y[];
- int *n;
- int ix[], iy[]; {
- ps_shorten_path (x, y, *n, ix, iy);
- }
-
- void ps_pie (x, y, radius, az1, az2, r, g, b, outline)
- double x, y, radius, az1, az2;
- int r, g, b;
- int outline; {
- int ix, iy, ir;
-
- ix = rint (x * ps.scale);
- iy = rint (y * ps.scale);
- ir = rint (radius * ps.scale);
- if (r < 0) /* Outline only */
- fprintf (ps.fp, "%d %d M %d %d %d %lg %lg P4\n",
- ix, iy, ix, iy, ir, az1, az2);
- if (r != g || g != b) /* color */
- fprintf (ps.fp, "%d %d M %.3lg %.3lg %.3lg %d %d %d %lg %lg P%d\n",
- ix, iy, r * I_255, g * I_255, b * I_255, ix, iy, ir, az1, az2, outline+2);
- else /* Grayshade */
- fprintf (ps.fp, "%d %d M %.3lg %d %d %d %lg %lg P%d\n", ix, iy, r * I_255, ix, iy, ir, az1, az2, outline);
- ps.npath = 0;
- }
-
- /* fortran interface */
- int ps_pie_ (x, y, radius, az1, az2, r, g, b, outline)
- double *x, *y, *radius, *az1, *az2;
- int *r, *g, *b;
- int *outline; {
- ps_pie (*x, *y, *radius, *az1, *az2, *r, *g, *b, *outline);
- }
-
- void ps_plot (x, y, pen)
- double x, y;
- int pen; {
- int ix, iy, idx, idy;
-
- ix = rint (x*ps.scale);
- iy = rint (y*ps.scale);
- if (abs (pen) == 2) { /* Convert absolute draw to relative draw */
- idx = ix - ps.ix;
- idy = iy - ps.iy;
- if (idx == 0 && idy == 0) return;
- fprintf (ps.fp, "%d %d D\n", idx, idy);
- ps.npath++;
- }
- else {
- idx = ix;
- idy = iy;
- fprintf (ps.fp, "%d %d M\n", idx, idy);
- ps.npath = 1;
- }
- if (pen == -2) fprintf (ps.fp, "S\n");
- ps.ix = ix;
- ps.iy = iy;
- if ((ps.npath + ps.clip_path_length) > ps.v1_path_length_limit) {
- fprintf (ps.fp, "S %d %d M\n", ix, iy);
- ps.npath = 1;
- }
- }
-
- /* fortran interface */
- int ps_plot_ (x, y, pen)
- double *x, *y;
- int *pen; {
- ps_plot (*x, *y, *pen);
- }
-
- void ps_plotend (lastpage)
- int lastpage; {
-
- ps_imagefill_cleanup ();
- if (lastpage) {
- fprintf (ps.fp, "%%%%Trailer\n");
- fprintf (ps.fp, "%% Reset translations and scale and call showpage\n");
- fprintf (ps.fp, "S %d %d T", -(int) rint (ps.xoff * ps.scale), -(int) rint (ps.yoff * ps.scale));
- fprintf (ps.fp, " %lg %lg scale",
- ps.scale/(ps.points_pr_unit * ps.xscl), ps.scale/(ps.points_pr_unit * ps.yscl));
- if (ps.mode == 0) fprintf (ps.fp, " -90 R %d 0 T", -(int)rint (ps.p_width * ps.points_pr_unit));
- fprintf (ps.fp, " showpage\n\n");
- fprintf (ps.fp, "end\n");
- }
- else
- fprintf (ps.fp, "S\n");
- if (ps.fp != stdout) fclose (ps.fp);
- if (ps.max_path_length > ps.v1_path_length_limit) fprintf (stderr, "pslib Warning: Some polygons may have been too long (%d)!\n", ps.max_path_length);
- }
-
- /* fortran interface */
- int ps_plotend_ (lastpage)
- int *lastpage; {
- ps_plotend (*lastpage);
- }
-
- int ps_plotinit (plotfile, overlay, mode, xoff, yoff, xscl, yscl, ncopies, dpi, unit, page_width, rgb, eps)
- char *plotfile; /* Name of output file or NULL for standard output */
- double xoff, yoff; /* Sets a new origin relative to old */
- double xscl, yscl; /* Global scaling, usually left to 1,1 */
- double page_width; /* Physical width of paper used (8.5 inch for regular laserplotter) */
- int overlay; /* FALSE means print headers and macros first */
- int mode; /* First bit 0 = Landscape, 1 = Portrait, Second bit 1 = no Euro
- Third bit 1 = hex image, 0 = bin image */
- int ncopies; /* Number of copies for this plot */
- int dpi; /* Plotter resolution in dots-per-inch */
- int unit; /* 0 = cm, 1 = inch, 2 = meter */
- int rgb[]; /* array with Color of page (paper) */
- struct EPS *eps; /* !! Fortran version (ps_plotinit_) does not have this argument !! */
- {
- int i, euro;
- time_t right_now, time();
- char openmode[2];
- double scl;
-
- ps.hex_image = (mode & 4) ? TRUE : FALSE;
- ps.v1_path_length_limit = MAX_PATH;
- ps.p_width = page_width;
- ps.font_no = 0;
- ps.scale = (double)dpi; /* Dots pr. unit resolution of output device */
- ps.points_pr_unit = 72.0;
- if (unit == 0) ps.points_pr_unit /= 2.54;
- if (unit == 2) ps.points_pr_unit /= 0.0254;
- euro = (mode & 2); /* If 2nd bit set then European character encoding is wanted */
- mode &= 1;
- if (plotfile == NULL || plotfile[0] == 0)
- ps.fp = stdout;
- else {
- (overlay) ? strcpy (openmode, "a") : strcpy (openmode, "w");
- if ((ps.fp = fopen (plotfile, openmode)) == NULL) {
- fprintf (stderr, "pslib: Cannot create/open file : %s\n", plotfile);
- return (-1);
- }
- }
- right_now = time ((time_t *)0);
- fprintf (ps.fp, "%%!PS-Adobe-3.0 EPSF-3.0\n");
- ps.mode = !(overlay && mode);
- ps.xscl = xscl;
- ps.xoff = xoff;
- ps.yscl = yscl;
- ps.yoff = yoff;
- strcpy (ps.bw_format, "%.3lg "); /* Default format used for grayshade value */
- strcpy (ps.rgb_format, "%.3lg %.3lg %.3lg "); /* Same, for color triplets */
- if (!overlay) {
- /* Write definitions of macros to plotfile */
-
- if (eps) {
- if (mode == 0)
- fprintf (ps.fp, "%%%%BoundingBox: %d %d %d %d\n", eps->x0, eps->y0, eps->y1, eps->x1);
- else
- fprintf (ps.fp, "%%%%BoundingBox: %d %d %d %d\n", eps->x0, eps->y0, eps->x1, eps->y1);
- fprintf (ps.fp, "%%%%Title: %s\n", eps->title);
- fprintf (ps.fp, "%%%%Creator: %s\n", eps->name);
- fprintf (ps.fp, "%%%%DocumentNeededResources: font");
- for (i = 0; eps->font[i]; i++) fprintf (ps.fp, " %s", eps->font[i]);
- fprintf (ps.fp, "\n");
- }
- else {
- fprintf (ps.fp, "%%%%BoundingBox: 0 0 612 792\n");
- fprintf (ps.fp, "%%%%Title: pslib v%lg document\n", Version);
- fprintf (ps.fp, "%%%%Creator: ???\n");
- }
- fprintf (ps.fp, "%%%%CreationDate: %s", ctime(&right_now));
- fprintf (ps.fp, "%%%%Orientation: Portrait\n");
- fprintf (ps.fp, "%%%%EndComments\n\n");
-
- fprintf (ps.fp, "%%%%BeginProlog\n\n");
- fprintf (ps.fp, "%% Begin pslib header\n\n");
-
- fprintf (ps.fp, "250 dict begin\n\n");
- fprintf (ps.fp, "/A /setgray load def\n");
- fprintf (ps.fp, "/B /setdash load def\n");
- fprintf (ps.fp, "/C /setrgbcolor load def\n");
- fprintf (ps.fp, "/D /rlineto load def\n");
- fprintf (ps.fp, "/E {dup stringwidth pop} bind def\n");
- fprintf (ps.fp, "/F /fill load def\n");
- fprintf (ps.fp, "/G /rmoveto load def\n");
- fprintf (ps.fp, "/L /lineto load def\n");
- fprintf (ps.fp, "/M {stroke moveto} bind def\n");
- fprintf (ps.fp, "/m {moveto} bind def\n");
- fprintf (ps.fp, "/N /newpath load def\n");
- fprintf (ps.fp, "/O {M {D} repeat P V C F U S} def\n");
- fprintf (ps.fp, "/o {M {D} repeat P V A F U S} def\n");
- fprintf (ps.fp, "/P /closepath load def\n");
- fprintf (ps.fp, "/Q {M {D} repeat P V C F U N} def\n");
- fprintf (ps.fp, "/q {M {D} repeat P V A F U N} def\n");
- fprintf (ps.fp, "/t {M {D} repeat P S} def\n");
- fprintf (ps.fp, "/R /rotate load def\n");
- fprintf (ps.fp, "/S /stroke load def\n");
- fprintf (ps.fp, "/T /translate load def\n");
- fprintf (ps.fp, "/U /grestore load def\n");
- fprintf (ps.fp, "/V /gsave load def\n");
- fprintf (ps.fp, "/W /setlinewidth load def\n");
- fprintf (ps.fp, "/X {M dup 0 D dup -0.5 mul dup G 0 exch D S} bind def\n");
- fprintf (ps.fp, "/Y {findfont exch scalefont setfont} bind def\n");
- fprintf (ps.fp, "/Z /show load def\n");
- fprintf (ps.fp, "/A0 {0 exch M 0 D D D D D 0 D P V A F U N} bind def\n");
- fprintf (ps.fp, "/A1 {0 exch M 0 D D D D D 0 D P V A F U S} bind def\n");
- fprintf (ps.fp, "/A2 {0 exch M 0 D D D D D 0 D P V C F U N} bind def\n");
- fprintf (ps.fp, "/A3 {0 exch M 0 D D D D D 0 D P V C F U S} bind def\n");
- fprintf (ps.fp, "/A4 {0 exch M 0 D D D D D 0 D P S} bind def\n");
- fprintf (ps.fp, "/C0 {0 360 arc V A F U N} bind def\n");
- fprintf (ps.fp, "/C1 {0 360 arc V A F U S} bind def\n");
- fprintf (ps.fp, "/C2 {0 360 arc V C F U N} bind def\n");
- fprintf (ps.fp, "/C3 {0 360 arc V C F U S} bind def\n");
- fprintf (ps.fp, "/C4 {0 360 arc S} bind def\n");
- fprintf (ps.fp, "/D0 {M 5 {dup} repeat D neg exch D neg exch neg D P V A F U N} bind def\n");
- fprintf (ps.fp, "/D1 {M 5 {dup} repeat D neg exch D neg exch neg D P V A F U S} bind def\n");
- fprintf (ps.fp, "/D2 {M 5 {dup} repeat D neg exch D neg exch neg D P V C F U N} bind def\n");
- fprintf (ps.fp, "/D3 {M 5 {dup} repeat D neg exch D neg exch neg D P V C F U S} bind def\n");
- fprintf (ps.fp, "/D4 {M 5 {dup} repeat D neg exch D neg exch neg D P S} bind def\n");
- fprintf (ps.fp, "/R0 {M dup 0 D exch 0 exch D neg 0 D P V A F U N} bind def\n");
- fprintf (ps.fp, "/R1 {M dup 0 D exch 0 exch D neg 0 D P V A F U S} bind def\n");
- fprintf (ps.fp, "/R2 {M dup 0 D exch 0 exch D neg 0 D P V C F U N} bind def\n");
- fprintf (ps.fp, "/R3 {M dup 0 D exch 0 exch D neg 0 D P V C F U S} bind def\n");
- fprintf (ps.fp, "/R4 {M dup 0 D exch 0 exch D neg 0 D P S} bind def\n");
- fprintf (ps.fp, "/S0 {M dup dup 0 D 0 exch D neg 0 D P V A F U N} bind def\n");
- fprintf (ps.fp, "/S1 {M dup dup 0 D 0 exch D neg 0 D P V A F U S} bind def\n");
- fprintf (ps.fp, "/S2 {M dup dup 0 D 0 exch D neg 0 D P V C F U N} bind def\n");
- fprintf (ps.fp, "/S3 {M dup dup 0 D 0 exch D neg 0 D P V C F U S} bind def\n");
- fprintf (ps.fp, "/S4 {M dup dup 0 D 0 exch D neg 0 D P S} bind def\n");
- fprintf (ps.fp, "/T0 {M dup 0 D dup -0.5 mul exch 0.866025 mul D P V A F U N} bind def\n");
- fprintf (ps.fp, "/T1 {M dup 0 D dup -0.5 mul exch 0.866025 mul D P V A F U S} bind def\n");
- fprintf (ps.fp, "/T2 {M dup 0 D dup -0.5 mul exch 0.866025 mul D P V C F U N} bind def\n");
- fprintf (ps.fp, "/T3 {M dup 0 D dup -0.5 mul exch 0.866025 mul D P V C F U S} bind def\n");
- fprintf (ps.fp, "/T4 {M dup 0 D dup -0.5 mul exch 0.866025 mul D P S} bind def\n");
- fprintf (ps.fp, "/I0 {M dup 0 D dup -0.5 mul exch -0.866025 mul D P V A F U N} bind def\n");
- fprintf (ps.fp, "/I1 {M dup 0 D dup -0.5 mul exch -0.866025 mul D P V A F U S} bind def\n");
- fprintf (ps.fp, "/I2 {M dup 0 D dup -0.5 mul exch -0.866025 mul D P V C F U N} bind def\n");
- fprintf (ps.fp, "/I3 {M dup 0 D dup -0.5 mul exch -0.866025 mul D P V C F U S} bind def\n");
- fprintf (ps.fp, "/I4 {M dup 0 D dup -0.5 mul exch -0.866025 mul D P S} bind def\n");
- fprintf (ps.fp, "/E0 {V T dup 0 exch M 0.726542528 mul -72 R dup 0 D 4 {72 R dup 0 D -144 R dup 0 D} repeat pop P V A F U N U} bind def\n");
- fprintf (ps.fp, "/E1 {V T dup 0 exch M 0.726542528 mul -72 R dup 0 D 4 {72 R dup 0 D -144 R dup 0 D} repeat pop P V A F U S U} bind def\n");
- fprintf (ps.fp, "/E2 {V T dup 0 exch M 0.726542528 mul -72 R dup 0 D 4 {72 R dup 0 D -144 R dup 0 D} repeat pop P V C F U N U} bind def\n");
- fprintf (ps.fp, "/E3 {V T dup 0 exch M 0.726542528 mul -72 R dup 0 D 4 {72 R dup 0 D -144 R dup 0 D} repeat pop P V C F U S U} bind def\n");
- fprintf (ps.fp, "/E4 {V T dup 0 exch M 0.726542528 mul -72 R dup 0 D 4 {72 R dup 0 D -144 R dup 0 D} repeat pop P S U} bind def\n");
- fprintf (ps.fp, "/H0 {V T dup dup 0.5 mul exch 0.866025404 mul M 5 {-60 R dup 0 D} repeat pop P V A F U N U} bind def\n");
- fprintf (ps.fp, "/H1 {V T dup dup 0.5 mul exch 0.866025404 mul M 5 {-60 R dup 0 D} repeat pop P V A F U S U} bind def\n");
- fprintf (ps.fp, "/H2 {V T dup dup 0.5 mul exch 0.866025404 mul M 5 {-60 R dup 0 D} repeat pop P V C F U N U} bind def\n");
- fprintf (ps.fp, "/H3 {V T dup dup 0.5 mul exch 0.866025404 mul M 5 {-60 R dup 0 D} repeat pop P V C F U S U} bind def\n");
- fprintf (ps.fp, "/H4 {V T dup dup 0.5 mul exch 0.866025404 mul M 5 {-60 R dup 0 D} repeat pop P S U} bind def\n");
- fprintf (ps.fp, "/P0 {arc P V A F U N} bind def\n");
- fprintf (ps.fp, "/P1 {arc P V A F U S} bind def\n");
- fprintf (ps.fp, "/P2 {arc P V C F U N} bind def\n");
- fprintf (ps.fp, "/P3 {arc P V C F U S} bind def\n");
- fprintf (ps.fp, "/P4 {arc P S} bind def\n");
- fprintf (ps.fp, "/a {P V A F U N} def\n");
- fprintf (ps.fp, "/b {P V A F U S} def\n");
- fprintf (ps.fp, "/c {P V C F U N} def\n");
- fprintf (ps.fp, "/d {P V C F U S} def\n");
- fprintf (ps.fp, "/p {P S} def\n");
-
- /* Define font macros (see pslib.h for details on how to add fonts) */
-
- for (i = 0; i < N_FONTS; i++) fprintf (ps.fp, "/F%d {/%s Y} bind def\n", i, ps_font_name[i]);
-
- if (euro) init_euro_header(eps);
-
- fprintf (ps.fp, "/#copies %d def\n\n", ncopies);
- fprintf (ps.fp, "%%%%EndProlog\n\n");
-
- fprintf (ps.fp, "%%%%BeginSetup\n\n");
- fprintf (ps.fp, "%% Init coordinate system and scales\n");
- scl = ps.points_pr_unit / ps.scale;
- fprintf (ps.fp, "%% Scale is originally set to %lg, which means that\n", scl);
- if (unit == 0) { /* CM used as unit */
- /* ps.scale /= 2.54; */
- fprintf (ps.fp, "%% 1 cm on the paper equals %d Postscript units\n", (int)ps.scale);
- }
- else if (unit == 1) /* INCH used as unit */
- fprintf (ps.fp, "%% 1 inch on the paper equals %d Postscript units\n", (int)ps.scale);
- else if (unit == 2) { /* M used as unit */
- /* ps.scale /= 0.0254; */
- fprintf (ps.fp, "%% 1 m on the paper equals %d Postscript units\n", (int)ps.scale);
- }
- else {
- fprintf (stderr, "pslib: Measure unit not valid!\n");
- exit (-1);
- }
-
- xscl *= scl;
- yscl *= scl;
- if (mode == 0) /* Landscape, 1 == Portrait */
- fprintf (ps.fp, "%d 0 T 90 R\n", (int)rint (ps.p_width * ps.points_pr_unit));
- fprintf (ps.fp, "%lg %lg scale\n", xscl, yscl);
- }
- if (!(xoff == 0.0 && yoff == 0.0)) fprintf (ps.fp, "%d %d T\n", (int)rint(xoff*ps.scale), (int)rint(yoff*ps.scale));
- ps_setpaint (0, 0, 0);
- fprintf (ps.fp, "%% End of pslib header\n");
- if (!overlay) fprintf (ps.fp, "%%%%EndSetup\n");
- if (!overlay && !(rgb[0] == rgb[1] && rgb[1] == rgb[2] && rgb[0] == 255)) { /* Change background color */
- if (rgb[0] != rgb[1] || rgb[1] != rgb[2])
- fprintf (ps.fp, "clippath %.3lg %.3lg %.3lg C F N\n", rgb[0] * I_255, rgb[1] * I_255, rgb[2] * I_255);
- else
- fprintf (ps.fp, "clippath %.3lg A F N\n", rgb[0] * I_255);
- }
-
- /* Initialize global variables */
-
- ps.npath = ps.clip_path_length = ps.max_path_length = 0;
- memset ((char *) ps_pattern_status, 0, 2 * N_PATTERNS);
- return (0);
- }
-
- /* fortran interface */
- int ps_plotinit_ (plotfile, overlay, mode, xoff, yoff, xscl, yscl, ncopies, dpi, unit, page_width, rgb, nlen)
- char *plotfile;
- double *xoff, *yoff;
- double *xscl, *yscl;
- double *page_width;
- int *overlay;
- int *mode;
- int *ncopies;
- int *dpi;
- int *unit;
- int rgb[];
- int nlen; {
- ps_plotinit (plotfile, *overlay, *mode, *xoff, *yoff, *xscl, *yscl, *ncopies, *dpi, *unit, *page_width, rgb, (struct EPS *)NULL);
- }
-
- void ps_plotr (x, y, pen)
- double x, y;
- int pen; {
- int ix, iy;
-
- ix = rint (x * ps.scale);
- iy = rint (y * ps.scale);
- if (ix == 0 && iy == 0) return;
- ps.npath++;
- if (abs (pen) == 2)
- fprintf (ps.fp, "%d %d D\n", ix, iy);
- else {
- fprintf (ps.fp, "%d %d G\n", ix, iy);
- ps.npath = 1;
- }
- if (pen == -2) fprintf (ps.fp, "S\n");
- ps.ix += ix; /* Update absolute position */
- ps.iy += iy;
- }
-
- /* fortran interface */
- int ps_plotr_ (x, y, pen)
- double *x, *y;
- int *pen; {
- ps_plotr (*x, *y, *pen);
- }
-
- void ps_polygon (x, y, n, r, g, b, outline)
- double *x, *y;
- int n, r, g, b;
- int outline; {
- int split;
- char mode;
-
- split = (r < 0); /* Can only split if we need outline only */
- if (outline >= 0) ps_line (x, y, n, 1, FALSE, split); /* No stroke or close path yet */
- ps.npath = 0;
-
- ps.max_path_length = MAX ((n + ps.clip_path_length), ps.max_path_length);
-
- if (split) { /* Outline only */
- mode = 'p';
- outline = 0;
- }
- else if (r != g || g != b) {
- mode = 'c';
- fprintf (ps.fp, ps.rgb_format, r * I_255, g * I_255, b * I_255);
- }
- else {
- mode = 'a';
- fprintf (ps.fp, ps.bw_format, r * I_255);
- }
- if (outline > 0) mode += outline;
- fprintf (ps.fp, "%c\n", mode);
- if (outline < 0) {
- fprintf (ps.fp, "\nN U\n%%Clipping is currently OFF\n");
- ps.clip_path_length = 0;
- }
- }
-
- /* fortran interface */
- int ps_polygon_ (x, y, n, r, g, b, outline)
- double x[], y[];
- int *n, *r, *g, *b;
- int *outline; {
- ps_polygon (x, y, *n, *r, *g, *b, *outline);
- }
-
-
- void ps_patch (x, y, np, r, g, b, outline)
- double x[], y[];
- int np, r, g, b;
- int outline; {
- /* Like ps_polygon but intended for small polygons (< 20 points). No checking for
- * shorter path by calling ps_shorten_path as in ps_polygon.
- *
- * Thus, the usage is (with xi,yi being absolute coordinate for point i and dxi the increment
- * from point i to i+1, and r,g,b in the range 0.0-1.0. Here, n = np-1. O means draw outline,
- * Q means no outline. Upper case for rgb, lower case for gray.
- *
- * r g b dx2 dy2 dx1 dy1 dx0 dy0 n x0 y0 Q
- * r dx2 dy2 dx1 dy1 dx0 dy0 n x0 y0 q
- * r g b dx1 dy1 dx0 dy0 n x0 y0 O
- * r dx1 dy1 dx0 dy0 n x0 y0 o
- * dx1 dy1 dx0 dy0 n x0 y0 t (If r < 0 then outline only)
- */
-
- int i, n, n1, ix[20], iy[20];
- char mode;
-
- if (np > 20) { /* Must call ps_polygon instead */
- ps_polygon ( x, y, np, r, g, b, outline);
- return;
- }
-
- ix[0] = rint (x[0] * ps.scale); /* Convert inch to absolute pixel position for start of quadrilateral */
- iy[0] = rint (y[0] * ps.scale);
-
- for (i = n = 1, n1 = 0; i < np; i++) { /* Same but check if new point represent a different pixel */
- ix[n] = rint (x[i] * ps.scale);
- iy[n] = rint (y[i] * ps.scale);
- if (ix[n] != ix[n1] || iy[n] != iy[n1]) n++, n1++;
- }
- if (ix[0] == ix[n1] && iy[0] == iy[n1]) n--, n1--; /* Closepath will do this automatically */
-
- if (n < 3) return; /* 2 points or less don't make a polygon */
-
- mode = (outline) ? 'O' : 'Q';
-
- if (r < 0) /* Outline only */
- mode = 't';
- else if (r != g || r != b) /* Must use color */
- fprintf (ps.fp, ps.rgb_format, r * I_255, g * I_255, b * I_255); /* Convert from 0-255 to 0-1 */
- else { /* Grayshade */
- mode += ('a' - 'A'); /* Change mode from upper to lower case for grayshade operator */
- fprintf (ps.fp, ps.bw_format, r * I_255);
- }
-
- n--;
- n1 = n;
- for (i = n - 1; i != -1; i--, n--) fprintf (ps.fp, "%d %d ", ix[n] - ix[i], iy[n] - iy[i]);
- fprintf (ps.fp, "%d %d %d %c\n", n1, ix[0], iy[0], mode);
- }
-
- /* fortran interface */
-
- int ps_patch_ (x, y, n, r, g, b, outline)
- double x[], y[];
- int *n, *r, *g, *b, *outline; {
- ps_patch (x, y, *n, *r, *g, *b, *outline);
- }
-
- void ps_rect (x1, y1, x2, y2, r, g, b, outline)
- double x1, y1, x2, y2;
- int r, g, b;
- int outline; {
- int ix, iy, idx, idy;
-
- ix = rint (x1 * ps.scale);
- iy = rint (y1 * ps.scale);
- idx = rint (x2 * ps.scale) - ix;
- idy = rint (y2 * ps.scale) - iy;
- if (r < 0) /* Outline only */
- fprintf (ps.fp, "%d %d %d %d R4\n", idy, idx, ix, iy);
- else if (r != g || g != b) /* color */
- fprintf (ps.fp, "%.3lg %.3lg %.3lg %d %d %d %d R%d\n", r * I_255, g * I_255, b * I_255, idy, idx, ix, iy, outline+2);
- else /* Grayshade */
- fprintf (ps.fp, "%.3lg %d %d %d %d R%d\n", r * I_255, idy, idx, ix, iy, outline);
- ps.npath = 0;
- }
-
- /* fortran interface */
- int ps_rect_ (x1, y1, x2, y2, r, g, b, outline)
- double *x1, *y1, *x2, *y2;
- int *r, *g, *b;
- int *outline; {
- ps_rect (*x1, *y1, *x2, *y2, *r, *g, *b, *outline);
- }
-
- void ps_rotatetrans (x, y, angle)
- double x, y, angle; {
- int ix, iy;
- int go = FALSE;
-
- ix = rint (x * ps.scale);
- iy = rint (y * ps.scale);
- if (angle != 0.0) {
- fprintf (ps.fp, "%lg R", angle);
- go = TRUE;
- }
- if (ix != 0 || iy != 0) {
- if (go) putc (' ', ps.fp);
- fprintf (ps.fp, "%d %d T", ix, iy);
- }
- putc ('\n', ps.fp);
- }
-
- /* fortran interface */
- int ps_rotatetrans_ (x, y, angle)
- double *x, *y, *angle; {
- ps_rotatetrans (*x, *y, *angle);
- }
-
- void ps_setdash (pattern, offset)
- char *pattern; /* Line structure in Postscript units */
- int offset; { /* offset from plotpoint in " units */
- /* Examples:
- * pattern = "4 4", offset = 0:
- * 4 units of line, 4 units of space, start at current point
- * pattern = "5 3 1 3", offset = 2:
- * 5 units line, 3 units space, 1 unit line, 3 units space, start
- * 2 units from curr. point.
- */
- if (pattern)
- fprintf (ps.fp, "S [%s] %d B\n", pattern, offset);
- else
- fprintf (ps.fp, "S [] 0 B\n"); /* Reset to continous line */
- ps.npath = 0;
- }
-
- /* fortran interface */
- int ps_setdash_ (pattern, offset, nlen)
- char *pattern;
- int nlen;
- int *offset; {
- ps_setdash (pattern, *offset);
- }
-
- void ps_setfont (font_no)
- int font_no; {
- if (font_no < 0 || font_no >= N_FONTS)
- fprintf (stderr, "pslib: Selected font out of range (%d), ignored\n", font_no);
- else
- ps.font_no = font_no;
- }
-
- /* fortran interface */
- int ps_setfont_ (font_no)
- int *font_no; {
- ps_setfont (*font_no);
- }
-
- void ps_setformat (n_decimals)
- int n_decimals; {
- /* Sets nmber of decimals used for rgb/gray specifications [3] */
- if (n_decimals < 1 || n_decimals > 3)
- fprintf (stderr, "pslib: Selected decimals for color out of range (%d), ignored\n", n_decimals);
- else {
- sprintf (ps.bw_format, "%%.%dlf \0", n_decimals);
- sprintf (ps.rgb_format, "%%.%dlf %%.%dlf %%.%dlf \0", n_decimals, n_decimals, n_decimals);
- }
- }
-
- /* fortran interface */
- int ps_setformat_ (n_decimals)
- int *n_decimals; {
- ps_setformat (*n_decimals);
- }
-
- void ps_setline (linewidth)
- int linewidth; {
- if (linewidth < 0)
- fprintf (stderr, "pslib: Selected linewidth is negative (%d), ignored\n", linewidth);
- else
- fprintf (ps.fp, "S %d W\n",linewidth);
- }
-
- /* fortan interface */
- int ps_setline_ (linewidth)
- int *linewidth; {
- ps_setline (*linewidth);
- }
-
- void ps_setpaint (r, g, b)
- int r, g, b; {
- if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255)
- fprintf (stderr, "pslib: Selected color is out of range (%d/%d/%d), ignored\n", r, g, b);
- else {
- if (r != g || g != b) /* color */
- fprintf (ps.fp, "S %.3lg %.3lg %.3lg C\n", (r * I_255), (g * I_255), (b * I_255));
- else
- fprintf (ps.fp, "S %.3lg A\n", (r * I_255));
- }
- }
-
- /* fortran interface */
- int ps_setpaint_ (r, g, b)
- int *r, *g, *b; {
- ps_setpaint (*r, *g, *b);
- }
-
- void ps_square (x, y, side, r, g, b, outline)
- double x, y, side;
- int r, g, b;
- int outline; { /* see circle */
- int ds, ix, iy;
-
- ds = rint (side * ps.scale);
- side *= 0.5;
- ix = rint ((x - side) * ps.scale);
- iy = rint ((y - side) * ps.scale);
- if (r < 0) /* Outline only */
- fprintf (ps.fp, "%d %d %d S4\n", ds, ix, iy);
- else if (r != g || g != b) /* color */
- fprintf (ps.fp, "%.3lg %.3lg %.3lg %d %d %d S%d\n", r * I_255, g * I_255, b * I_255, ds, ix, iy, outline+2);
- else /* Grayshade */
- fprintf (ps.fp, "%.3lg %d %d %d S%d\n", r * I_255, ds, ix, iy, outline);
- ps.npath = 0;
- }
-
- /* fortran interface */
- int ps_square_ (x, y, side, r, g, b, outline)
- double *x, *y, *side;
- int *r, *g, *b;
- int *outline; {
- ps_square (*x, *y, *side, *r, *g, *b, *outline);
- }
-
- void ps_text (x, y, pointsize, text, angle, justify, form)
- double x, y, angle;
- char *text;
- int pointsize;
- int justify; /* indicates what x,y refers to, see fig */
- int form; { /* 0 = normal text, 1 = outline */
- /*
- * 9 10 11
- * |----------------|
- * 5 <textstring> 7
- * |----------------|
- * 1 2 3
- */
- char *tempstring, *piece, *piece2, *ptr, *string, op[16];
- int dy, i = 0, j, font;
- int sub, super, small, old_font;
- double height, small_size, size, scap_size, step, y0;
-
- if (strlen (text) >= 511) {
- fprintf (stderr, "pslib: text_item > 512 long!\n");
- return;
- }
-
- if (justify < 0) { /* Strip leading and trailing blanks */
- for (i = 0; text[i] == ' '; i++);
- for (j = strlen (text) - 1; text[j] == ' '; j--) text[j] = 0;
- }
- string = ps_prepare_text (&text[i]); /* Check for escape sequences */
-
- justify = abs (justify);
- height = pointsize / ps.points_pr_unit;
-
- /* Got to anchor point */
-
- ps.npath = 0;
- ps.ix = rint (x*ps.scale);
- ps.iy = rint (y*ps.scale);
- fprintf (ps.fp, "%d %d M ", ps.ix, ps.iy);
-
- if (angle != 0.0) fprintf (ps.fp, "V %.3lg R ", angle);
- y0 = -0.5 * height * ps_font_height[ps.font_no] * (justify/4);
- if (y0 != 0.0) fprintf (ps.fp, "0 %d G ",(int) rint(y0 * ps.scale));
- if (!strchr (string, '@')) { /* Plain text string */
- fprintf (ps.fp, "%d F%d ", (int) rint (height * ps.scale), ps.font_no);
- fprintf (ps.fp, "(%s) ", string);
- if ((justify %= 4) > 1) fprintf (ps.fp, "E %d div 0 G ",(justify - 4));
- (form == 0) ? fprintf (ps.fp, "Z") : fprintf (ps.fp, "true charpath S");
- (angle != 0.0) ? fprintf (ps.fp, " U\n") : fprintf (ps.fp, "\n");
- free (string);
- return;
- }
-
- /* Here, we have special request for Symbol font and sub/superscript
- * @~ toggles between Symbol font and default font
- * @%<fontno>% switches font number <fontno>; give @%% to reset
- * @- toggles between subscript and normal text
- * @+ toggles between superscript and normal text
- * @# toggles between Small caps and normal text
- * @! will make a composite character of next two characters
- * Use @@ to print a single @
- */
-
- piece = malloc (2048); piece[0] = 0;
- piece2 = malloc (512); piece2[0] = 0;
-
- font = old_font = ps.font_no;
- size = height;
- small_size = height * 0.7;
- scap_size = height * 0.85;
- step = 0.3 * height;
- sub = super = small = FALSE;
-
- if ((justify %= 4 ) > 1) {
- /* First we need to compute the justification. The PS interpreter must do this for us */
- tempstring = malloc ((unsigned) (strlen (string)+1)); /* Since strtok steps on it */
- strcpy (tempstring, string);
- ptr = strtok (tempstring, "@");
- fprintf (ps.fp, "0 "); /* Initialize stringlength */
- /*
- Modifications by J.Lillibridge: 5/18/94
- Handle the case where string starts with "~,-,+,#,!" WITHOUT a preceding "@".
- But, in addition, there IS an "@" escape sequence within the string (that's
- why we're here... plain text has already been printed above & we returned).
-
- This is a problem because "strtok" returns the first part of the string even
- if there isn't a leading "@". The "while(ptr)" loop below assumes each
- "piece" is preceded by the "@" escape character.
- */
- if(string[0] != '@') {
- fprintf (ps.fp, "%d F%d (%s) stringwidth pop add ",
- (int)rint(size*ps.scale), font, ptr);
- ptr = strtok ((char *)NULL, "@");
- }
-
- while (ptr) {
- if (ptr[0] == '!') { /* Composite character */
- ptr++;
- if (ptr[0] == '\\') /* Octal code */
- ptr += 4;
- else
- ptr++;
- strcpy (piece, ptr);
- }
- else if (ptr[0] == '~') { /* Symbol font toggle */
- font = (font == 12) ? ps.font_no : 12;
- ptr++;
- strcpy (piece, ptr);
- }
- else if (ptr[0] == '%') { /* Switch font option */
- ptr++;
- if (ptr[0] == '%')
- font = old_font;
- else {
- old_font = font;
- font = atoi (ptr);
- }
- while (*ptr != '%') ptr++;
- ptr++;
- strcpy (piece, ptr);
- }
- else if (ptr[0] == '-') { /* Subscript toggle */
- sub = !sub;
- size = (sub) ? small_size : height;
- ptr++;
- strcpy (piece, ptr);
- }
- else if (ptr[0] == '+') { /* Superscript toggle */
- super = !super;
- size = (super) ? small_size : height;
- ptr++;
- strcpy (piece, ptr);
- }
- else if (ptr[0] == '#') { /* Small caps toggle */
- small = !small;
- size = (small) ? scap_size : height;
- ptr++;
- (small) ? get_uppercase (piece, ptr) : (int) strcpy (piece, ptr);
- }
- else /* Not recognized or @@ for a single @ */
- strcpy (piece, ptr);
- if (strlen (piece) > 0) fprintf (ps.fp, "%d F%d (%s) stringwidth pop add ",
- (int)rint(size*ps.scale), font, piece);
- ptr = strtok ((char *)NULL, "@");
- }
- /* Now move currentpoint to reflect the justification */
- fprintf (ps.fp, "%d div 0 G\n", justify - 4);
- free (tempstring);
- }
-
- /* Now we can start printing text items */
-
- font = old_font = ps.font_no;
- if (form == 0)
- strcpy (op, "Z");
- else
- strcpy (op, "true charpath S");
- sub = super = small = FALSE;
- ptr = strtok (string, "@");
- size = height;
- /*
- Modifications by J.Lillibridge: 5/18/94
- Handle the case where string starts with "~,-,+,#,!" WITHOUT a preceding "@".
- But, in addition, there IS an "@" escape sequence within the string (that's
- why we're here... plain text has already been printed above & we returned).
-
- This is a problem because "strtok" returns the first part of the string even
- if there isn't a leading "@". The "while(ptr)" loop below assumes each
- "piece" is preceded by the "@" escape character.
- */
- if(string[0] != '@') {
- fprintf (ps.fp, "%d F%d (%s) %s\n",
- (int)rint(size*ps.scale), font, ptr, op);
- ptr = strtok ((char *)NULL, "@");
- }
-
- while (ptr) {
- if (ptr[0] == '!') { /* Composite character */
- ptr++;
- if (ptr[0] == '\\') { /* Octal code */
- strncpy (piece, ptr, 4);
- piece[4] = 0;
- ptr += 4;
- }
- else {
- piece[0] = ptr[0]; piece[1] = 0;
- ptr++;
- }
- if (ptr[0] == '\\') { /* Octal code again*/
- strncpy (piece2, ptr, 4);
- piece2[4] = 0;
- ptr += 4;
- }
- else {
- piece2[0] = ptr[0]; piece2[1] = 0;
- ptr++;
- }
- fprintf (ps.fp, "%d F%d (%s) dup stringwidth pop exch %s -2 div dup 0 G\n", (int)rint(size*ps.scale), font, piece2, op);
- fprintf (ps.fp, "%d F%d (%s) E -2 div dup 0 G exch %s sub neg dup 0 lt {pop 0} if 0 G\n", (int)rint(size*ps.scale), font, piece, op);
- strcpy (piece, ptr);
- }
- else if (ptr[0] == '~') { /* Symbol font */
- font = (font == 12) ? ps.font_no : 12;
- ptr++;
- strcpy (piece, ptr);
- }
- else if (ptr[0] == '%') { /* Switch font option */
- ptr++;
- if (*ptr == '%')
- font = old_font;
- else {
- old_font = font;
- font = atoi (ptr);
- }
- while (*ptr != '%') ptr++;
- ptr++;
- strcpy (piece, ptr);
- }
- else if (ptr[0] == '-') { /* Subscript */
- sub = !sub;
- size = (sub) ? small_size : height;
- dy = (sub) ? rint(-step*ps.scale) : rint(step*ps.scale);
- fprintf (ps.fp, "0 %d G\n", dy);
- ptr++;
- strcpy (piece, ptr);
- }
- else if (ptr[0] == '+') { /* Superscript */
- super = !super;
- size = (super) ? small_size : height;
- dy = (super) ? rint(step*ps.scale) : rint(-step*ps.scale);
- fprintf (ps.fp, "0 %d G\n", dy);
- ptr++;
- strcpy (piece, ptr);
- }
- else if (ptr[0] == '#') { /* Small caps */
- small = !small;
- size = (small) ? scap_size : height;
- ptr++;
- (small) ? get_uppercase (piece, ptr) : (int) strcpy (piece, ptr);
- }
- else
- strcpy (piece, ptr);
- if (strlen (piece) > 0)
- fprintf (ps.fp, "%d F%d (%s) %s\n",(int)rint(size*ps.scale), font, piece, op);
- ptr = strtok ((char *)NULL, "@");
- }
- if (angle != 0.0) fprintf (ps.fp, "U\n");
- free (piece);
- free (piece2);
- free (string);
- }
-
- /* fortan interface */
- int ps_text_ (x, y, pointsize, text, angle, justify, form, nlen)
- double *x, *y, *angle;
- char *text;
- int *pointsize;
- int *justify;
- int nlen;
- int *form; {
- ps_text (*x, *y, *pointsize, text, *angle, *justify, *form);
- }
-
- void ps_textbox2 (x, y, pointsize, text, angle, justify, outline, dx, dy, r, g, b)
- double x, y, angle;
- char *text;
- int pointsize, justify; /* indicates what x,y refers to, see fig */
- int outline;
- double dx, dy; /* Space between box border and text, in inches (or cm) */
- int r, g, b; { /* If r == -1 set up continued clip path instead */
- /*
- * 9 10 11
- * |----------------|
- * 5 <textstring> 7
- * |----------------|
- * 1 2 3
- */
- char *string;
- int i = 0, j, idx, idy;
- double height, y0;
-
- if (strlen (text) >= 511) {
- fprintf (stderr, "pslib: text_item > 512 long!\n");
- return;
- }
-
- if (justify < 0) { /* Strip leading and trailing blanks */
- for (i = 0; text[i] == ' '; i++);
- for (j = strlen (text) - 1; text[j] == ' '; j--) text[j] = 0;
- }
-
- string = ps_prepare_text (&text[i]);
-
- if (strchr (string, '@')) {
- free (string);
- return; /* Text string still contains escape sequence, box not yet supported */
- }
-
- fprintf (ps.fp, "\n%% ps_textbox begin:\n");
-
- height = pointsize / ps.points_pr_unit;
- justify = abs (justify);
- idx = rint (dx * ps.scale); idy = rint (dy * ps.scale);
-
- /* Got to anchor point */
-
- ps.ix = rint (x * ps.scale);
- ps.iy = rint (y * ps.scale);
- fprintf (ps.fp, "%d %d T 0 0 m ", ps.ix, ps.iy);
-
- y0 = -0.5 * height * ps_font_height[ps.font_no] * (justify/4);
- if (y0 != 0.0) fprintf (ps.fp, "0 %d G ",(int)rint (y0 * ps.scale));
- fprintf (ps.fp, "%d F%d (%s) ", (int)rint (height * ps.scale), ps.font_no, string);
- if ((justify %= 4) > 1) fprintf (ps.fp, "E %d div 0 G ",(justify - 4));
- fprintf (ps.fp, "false charpath flattenpath pathbbox\n");
- fprintf (ps.fp, "%d add /y2 exch def %d add /x2 exch def %d sub /y1 exch def %d sub /x1 exch def N\n",
- idy, idx, idy, idx);
- if (angle != 0.0) fprintf (ps.fp, "%.3lg R ", angle);
- fprintf (ps.fp, "x1 y1 m x2 y1 L x2 y2 L x1 y2 L P ");
- if (r != g || g != b)
- fprintf (ps.fp, "V %.3lg %.3lg %.3lg C F U ", (r * I_255), (g * I_255), (b * I_255));
- else if (r >= 0)
- fprintf (ps.fp, "V %.3lg A F U ", (r * I_255));
- if (r != -1)
- (outline) ? fprintf (ps.fp, "S\n") : fprintf (ps.fp, "N\n");
- if (angle != 0.0) fprintf (ps.fp, "%.3lg R ", -angle);
- fprintf (ps.fp, "%d %d T\n", -ps.ix, -ps.iy);
- fprintf (ps.fp, "%% ps_textbox end:\n\n");
-
- free (string);
- }
-
- void ps_textbox (x, y, pointsize, text, angle, justify, outline, dx, dy, r, g, b)
- double x, y, angle;
- char *text;
- int pointsize, justify; /* indicates what x,y refers to, see fig */
- int outline;
- double dx, dy; /* Space between box border and text, in inches */
- int r, g, b; {
- /*
- * 9 10 11
- * |----------------|
- * 5 <textstring> 7
- * |----------------|
- * 1 2 3
- */
- char *string;
- int i = 0, j, idx, idy;
- double height, y0;
-
- if (strlen (text) >= 511) {
- fprintf (stderr, "pslib: text_item > 512 long!\n");
- return;
- }
-
- if (justify < 0) { /* Strip leading and trailing blanks */
- for (i = 0; text[i] == ' '; i++);
- for (j = strlen (text) - 1; text[j] == ' '; j--) text[j] = 0;
- }
-
- string = ps_prepare_text (&text[i]);
-
- if (strchr (string, '@')) {
- free (string);
- return; /* Text string still contains escape sequence, box not yet supported */
- }
-
- fprintf (ps.fp, "\n%% ps_textbox begin:\n");
-
- height = pointsize / ps.points_pr_unit;
- justify = abs (justify);
- idx = rint (dx * ps.scale); idy = rint (dy * ps.scale);
-
- /* Got to anchor point */
-
- ps.ix = rint (x * ps.scale);
- ps.iy = rint (y * ps.scale);
- fprintf (ps.fp, "V %d %d T 0 0 M ", ps.ix, ps.iy);
-
- y0 = -0.5 * height * ps_font_height[ps.font_no] * (justify/4);
- if (y0 != 0.0) fprintf (ps.fp, "0 %d G ",(int)rint (y0 * ps.scale));
- fprintf (ps.fp, "%d F%d (%s) ", (int)rint (height * ps.scale), ps.font_no, string);
- if ((justify %= 4) > 1) fprintf (ps.fp, "E %d div 0 G ",(justify - 4));
- fprintf (ps.fp, "false charpath flattenpath pathbbox\n");
- fprintf (ps.fp, "%d add /y2 exch def %d add /x2 exch def %d sub /y1 exch def %d sub /x1 exch def N\n",
- idy, idx, idy, idx);
- if (angle != 0.0) fprintf (ps.fp, "%.3lg R ", angle);
- fprintf (ps.fp, "x1 y1 M x2 y1 L x2 y2 L x1 y2 L P V ");
- if (r != g || g != b)
- fprintf (ps.fp, "%.3lg %.3lg %.3lg C F U ", (r * I_255), (g * I_255), (b * I_255));
- else
- fprintf (ps.fp, "%.3lg A F U ", (r * I_255));
- (outline) ? fprintf (ps.fp, "S U\n") : fprintf (ps.fp, "N U\n");
- fprintf (ps.fp, "%% ps_textbox end:\n\n");
-
- free (string);
- }
-
- /* fortran interface */
- int ps_textbox_ (x, y, pointsize, text, angle, justify, outline, dx, dy, r, g, b, nlen)
- double *x, *y, *angle;
- char *text;
- int *pointsize, *justify;
- int *outline;
- double *dx, *dy;
- int nlen;
- int *r, *g, *b; {
- ps_textbox (*x, *y, *pointsize, text, *angle, *justify, *outline, *dx, *dy, *r, *g, *b);
- }
-
- void ps_transrotate (x, y, angle)
- double x, y, angle; {
- int ix, iy;
- int go = FALSE;
-
- ix = rint (x * ps.scale);
- iy = rint (y * ps.scale);
- if (ix != 0 || iy != 0) {
- fprintf (ps.fp, "%d %d T", ix, iy);
- go = TRUE;
- }
- if (angle != 0.0) {
- if (go) putc (' ', ps.fp);
- fprintf (ps.fp, "%lg R", angle);
- }
- putc ('\n', ps.fp);
- }
-
- /* fortran interface */
- int ps_transrotate_ (x, y, angle)
- double *x, *y, *angle; {
- ps_transrotate (*x, *y, *angle);
- }
-
- void ps_triangle (x, y, side, r, g, b, outline)
- double x, y, side;
- int r, g, b;
- int outline; { /* see circle */
- int ix, iy, is;
-
- ix = rint ((x-0.5*side) * ps.scale);
- iy = rint ((y-0.2886751*side) * ps.scale);
- is = rint (side * ps.scale);
- if (r < 0) /* Outline only */
- fprintf (ps.fp, "%d %d %d T4\n", is, ix, iy);
- else if (r != g || g != b) /* color */
- fprintf (ps.fp, "%.3lg %.3lg %.3lg %d %d %d T%d\n", r * I_255, g * I_255, b * I_255, is, ix, iy, outline+2);
- else /* Grayshade */
- fprintf (ps.fp, "%.3lg %d %d %d T%d\n", r * I_255, is, ix, iy, outline);
- ps.npath = 0;
- }
-
- /* fortran interface */
- int ps_triangle_ (x, y, side, r, g, b, outline)
- double *x, *y, *side;
- int *r, *g, *b;
- int *outline; {
- ps_triangle (*x, *y, *side, *r, *g, *b, *outline);
- }
-
- void ps_itriangle (x, y, side, r, g, b, outline) /* Inverted triangle */
- double x, y, side;
- int r, g, b;
- int outline; { /* see circle */
- int ix, iy, is;
-
- ix = rint ((x-0.5*side) * ps.scale);
- iy = rint ((y+0.2886751*side) * ps.scale);
- is = rint (side * ps.scale);
- if (r < 0) /* Outline only */
- fprintf (ps.fp, "%d %d %d I4\n", is, ix, iy);
- else if (r != g || g != b) /* color */
- fprintf (ps.fp, "%.3lg %.3lg %.3lg %d %d %d I%d\n", r * I_255, g * I_255, b * I_255, is, ix, iy, outline+2);
- else /* Grayshade */
- fprintf (ps.fp, "%.3lg %d %d %d I%d\n", r * I_255, is, ix, iy, outline);
- ps.npath = 0;
- }
-
- /* fortran interface */
- int ps_itriangle_ (x, y, side, r, g, b, outline)
- double *x, *y, *side;
- int *r, *g, *b;
- int *outline; {
- ps_itriangle (*x, *y, *side, *r, *g, *b, *outline);
- }
-
- void ps_vector (xtail, ytail, xtip, ytip, tailwidth, headlength, headwidth, headshape, r, g, b, outline)
- double xtail, ytail, xtip, ytip, tailwidth, headlength, headwidth, headshape;
- int r, g, b;
- int outline; {
- /* Will make sure that arrow has a finite width in PS coordinates */
-
- double angle;
- int w2, length, hw, hl, hl2, hw2, l2;
-
- length = rint (hypot ((xtail-xtip), (ytail-ytip)) * ps.scale);
- if (length == 0) return;
-
- angle = atan2 ((ytip-ytail),(xtip-xtail)) * R2D;
- fprintf (ps.fp, "V %d %d T", (int)rint (xtail * ps.scale), (int)rint (ytail * ps.scale));
- if (angle != 0.0) fprintf (ps.fp, " %lg R", angle);
- w2 = rint (0.5 * tailwidth * ps.scale); if (w2 == 0) w2 = 1;
- hw = rint (headwidth * ps.scale); if (hw == 0) hw = 1;
- hl = rint (headlength * ps.scale);
- hl2 = rint (0.5 * headshape * headlength * ps.scale);
- hw2 = hw - w2;
- l2 = length - hl + hl2;
- if (r < 0) /* Outline only */
- fprintf (ps.fp, " %d %d %d %d %d %d %d %d %d %d %d A4 U\n",
- -l2, hl2, -hw2, -hl, hw, hl, hw, -hl2, -hw2, l2, -w2);
- else if (r != g || g != b) /* color */
- fprintf (ps.fp, " %.3lg %.3lg %.3lg %d %d %d %d %d %d %d %d %d %d %d A%d U\n",
- r * I_255, g * I_255, b * I_255, -l2, hl2, -hw2, -hl, hw, hl, hw, -hl2, -hw2, l2, -w2, outline+2);
- else /* grayshade */
- fprintf (ps.fp, " %.3lg %d %d %d %d %d %d %d %d %d %d %d A%d U\n",
- r * I_255, -l2, hl2, -hw2, -hl, hw, hl, hw, -hl2, -hw2, l2, -w2, outline);
- }
-
- /* fortran interface */
- int ps_vector_ (xtail, ytail, xtip, ytip, tailwidth, headlength, headwidth, headshape, r, g, b, outline)
- double *xtail, *ytail, *xtip, *ytip, *tailwidth, *headlength, *headwidth, *headshape;
- int *r, *g, *b;
- int *outline; {
- ps_vector (*xtail, *ytail, *xtip, *ytip, *tailwidth, *headlength, *headwidth, *headshape, *r, *g, *b, *outline);
- }
-
- /* Support functions used in ps_* functions. No Fortran bindings needed */
-
- char *get_icon (file, nx, ny, invert)
- char *file;
- int *nx, *ny, invert; {
- int i, n_items, n_int, j, k, n_read, integer, n_alloc, n_lines, last;
- unsigned short int *pattern;
- char *out, t[8][7], line[80], width[12], height[12];
- FILE *fp;
-
- if ((fp = fopen (file, "r")) == NULL) {
- fprintf (stderr, "pslib: Cannot open file %s\n", file);
- return ((char *)NULL);
- }
-
- fgets (line, 80, fp);
- line[strlen(line)-1] = 0;
- sscanf (&line[3], "%*[^,], %[^,], %[^,]", width, height);
- i = 0; while (width[i] != '=') i++;
- *nx = atoi (&width[i+1]);
- i = 0; while (height[i] != '=') i++;
- *ny = atoi (&height[i+1]);
- fgets (line, 80, fp);
- line[strlen(line)-1] = 0;
- n_items = (*nx) * (*ny) / 4;
- n_int = n_items / 4;
- out = malloc ( (unsigned) (n_items+1));
- out[0] = 0;
- n_alloc = ceil (n_int / 8.0) * n_int;
- pattern = (unsigned short int *) malloc ((unsigned)n_alloc);
- n_lines = n_items / 32;
- for (i = k = 0; i < n_lines; i++) {
- fgets (line, 80, fp);
- line[strlen(line)-1] = 0;
- last = (i == (n_lines - 1));
- if (last) {
- n_read = sscanf (&line[1], "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,]", t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7]);
- if (n_read == 4) sscanf (&line[1], "%[^,],%[^,],%[^,],%[^,]", t[4], t[5], t[6], t[7]); /* New style icon file */
- }
- else {
- n_read = sscanf (&line[1], "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],", t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7]);
- if (n_read == 4) sscanf (&line[1], "%[^,],%[^,],%[^,],%[^,],", t[4], t[5], t[6], t[7]); /* New style icon file */
- }
- for (j = 0; j < 8; j++, k++) {
- sscanf (&t[j][2], "%x", &integer);
- pattern[k] = integer;
- }
- }
- fclose (fp);
- if (invert) for (k = 0; k < n_int; k++) pattern[k] = ~pattern[k];
- for (k = 0; k < n_int; k++) {
- sprintf (t[0], "%.4x", (int)pattern[k]);
- strcat (out, t[0]);
- }
- out[n_items] = 0;
- free ((char *)pattern);
- return (out);
- }
-
- int get_uppercase (new, old)
- char *new, *old; {
- int i = 0;
- while (old[i]) {
- new[i] = toupper ((int)old[i]);
- i++;
- }
- new[i] = 0;
- }
-
- void init_euro_header(eps)
- struct EPS *eps;
- /*-------------- European header definition -------------------*/
- {
- int i;
-
- fprintf (ps.fp,"%% START OF EUROPEAN FONT DEFINITION\n");
- fprintf (ps.fp, "%% Reencode standard font map to European font map\n\
- %%\n\
- /reencsmalldict 12 dict def\n\
- /ReEncodeSmall\n\
- { reencsmalldict begin\n\
- /newcodesandnames exch def\n\
- /newfontname exch def\n\
- /basefontname exch def\n\
- /basefontdict basefontname findfont def\n\
- /newfont basefontdict maxlength dict def\n\
- basefontdict\n\
- { exch dup /FID ne \n\
- { dup /Encoding eq\n\
- { exch dup length array copy\n\
- newfont 3 1 roll put }\n\
- { exch newfont 3 1 roll put }\n\
- ifelse\n\
- }\n\
- { pop pop }\n\
- ifelse\n\
- } forall\n\
- newfont /FontName newfontname put\n\
- newcodesandnames aload pop\n\
- newcodesandnames length 2 idiv\n\
- { newfont /Encoding get 3 1 roll put }\n\
- repeat\n\
- newfontname newfont definefont pop\n\
- end\n\
- } def\n\
- \n\
- /eurovec[\n\
- 8#260 /Aacute\n\
- 8#265 /Acircumflex\n\
- 8#276 /Adieresis\n\
- 8#300 /Agrave\n\
- 8#311 /Eacute\n\
- 8#314 /Ecircumflex\n\
- 8#321 /Edieresis\n\
- 8#322 /Egrave\n\
- 8#323 /Iacute\n\
- 8#324 /Icircumflex\n\
- 8#325 /Idieresis\n\
- 8#326 /Igrave\n\
- 8#327 /Oacute\n\
- 8#330 /Ocircumflex\n\
- 8#331 /Odieresis\n\
- 8#332 /Ograve\n\
- 8#333 /Uacute\n\
- 8#334 /Ucircumflex\n\
- 8#335 /Udieresis\n\
- 8#336 /Ugrave\n\
- 8#337 /aacute\n\
- 8#340 /acircumflex\n\
- 8#342 /adieresis\n\
- 8#344 /agrave\n\
- 8#345 /eacute\n\
- 8#346 /ecircumflex\n\
- 8#347 /edieresis\n\
- 8#350 /egrave\n\
- 8#354 /iacute\n\
- 8#355 /icircumflex\n\
- 8#356 /idieresis\n\
- 8#357 /igrave\n\
- 8#360 /oacute\n\
- 8#362 /ocircumflex\n\
- 8#363 /odieresis\n\
- 8#364 /ograve\n\
- 8#366 /uacute\n\
- 8#367 /ucircumflex\n\
- 8#370 /udieresis\n\
- 8#374 /ugrave\n\
- 8#375 /Aring\n\
- 8#376 /aring\n\
- ] def\n");
-
- /* Define European fonts */
- /* Only reencode fonts actually used */
- if (eps)
- for (i = 0; eps->font[i]; i++) ps_def_euro_font (eps->font[i]);
- else
- /* Must output all */
- for (i = 0; i < N_FONTS; i++) ps_def_euro_font (ps_font_name[i]);
-
- fprintf (ps.fp,"%% END OF EUROPEAN FONT DEFINITION\n");
- }
-
- void ps_def_euro_font (font)
- char *font; {
- fprintf (ps.fp, "/%s /%s eurovec ReEncodeSmall\n", font, font);
- }
-
- char *ps_prepare_text (text)
- char *text;
- /* Adds escapes for misc parenthesis, brackets etc.
- Will also translate to some European characters from the @a, @e
- etc escape sequences. Calling function must REMEMBER to free memory
- allocated by string */
- {
- char *string;
- int i=0, j=0;
-
- string = (char *) calloc (2048, sizeof(char));
- while (text[i]) {
- if (text[i] == '@') {
- i++;
- switch (text[i]) {
- case 'A':
- strcat (string, "\\375"); j += 4; i++;
- break;
- case 'E':
- strcat (string, "\\341"); j += 4; i++;
- break;
- case 'O':
- strcat (string, "\\351"); j += 4; i++;
- break;
- case 'a':
- strcat (string, "\\376"); j += 4; i++;
- break;
- case 'e':
- strcat (string, "\\372"); j += 4; i++;
- break;
- case 'o':
- strcat (string, "\\371"); j += 4; i++;
- break;
- case '@':
- /* Also now converts "@@" to the octal code for "@" = "\100".
- This was necessary since the system routine "strtok" gobbles up
- multiple @'s when parsing the string inside "ps_text", and thus
- didn't properly output a single "@" sign when encountering "@@".
- John L. Lillibridge: 4/6/95 [This was a problem on SGI; PW]
- */
-
- strcat (string, "\\100"); j += 4; i++;
- break;
- default:
- string[j++] = '@';
- string[j++] = text[i++];
- break;
- }
- }
- else {
- switch (text[i]) { /* NEED TO BE ESCAPED!!!! for PostScript*/
- case '{':
- case '}':
- case '[':
- case ']':
- case '(':
- case ')':
- case '<':
- case '>':
- if (j > 0 && string[MAX(j-1,0)] == '\\') /* ALREADY ESCAPED... */
- string[j++] = text[i++];
- else {
- strcat(string, "\\"); j++;
- string[j++] = text[i++];
- }
- break;
- default:
- string[j++] = text[i++];
- break;
- }
- }
- }
- return (string);
- }
-
-