/*--------------------------------------------------------------------
 *
 *	Copyright (c) 2009-2024 by the GMT Team (https://www.generic-mapping-tools.org/team.html)
 *	See LICENSE.TXT file for copying and redistribution conditions.
 *
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU Lesser General Public License as published by
 *	the Free Software Foundation; version 3 or any later version.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU Lesser General Public License for more details.
 *
 *	Contact info: www.generic-mapping-tools.org
 *--------------------------------------------------------------------*/
/*
 * This include file must be included by all programs using postscriptlight
 *
 * Authors:	Paul Wessel, Dept. of Geology and Geophysics, SOEST, U Hawaii
 *			   pwessel@hawaii.edu
 *		Remko Scharroo, Altimetrics
 *			   remko@altimetrics.com
 * Version:	6.0 [64-bit enabled API edition, decoupled from GMT]
 * Date:	13-OCT-2017
 */

/*!
 * \file postscriptlight.h
 * \brief Include file that must be included by all programs using postscriptlight
 */

#ifndef _POSTSCRIPTLIGHT_H
#define _POSTSCRIPTLIGHT_H

#define PSL_WITH_GMT4_SUPPORT	/* For as long as we want to be backwards compatible with GMT4 vectors */

#ifdef __cplusplus
extern "C" {
#endif

/* CMake definitions: This must be first! */
#include "psl_config.h"

/* Declaration modifiers for DLL support (MSC et al) */
#include "declspec.h"

#include <stdio.h>

#define PSL_MaxOpStack_Size	300000	/* As of GhostSCript 9.50; see declaration in gs_init.ps */

/* Number of PostScript points in one inch */

#define PSL_POINTS_PER_INCH	72.0
#define PSL_DOTS_PER_INCH	1200.0	/* Effective dots per inch resolution */
#define PSL_DOTS_PER_INCH_PATTERN	300.0	/* Effective dots per inch resolution for a bitmap pattern -Gp */
#define PSL_ALL_CLIP		INT_MAX	/* Terminates all clipping */

/* PSL codes for geometric symbols as expected by PSL_plotsymbol */

#define PSL_STAR		((int)'a')
#define PSL_CIRCLE		((int)'c')
#define PSL_DIAMOND		((int)'d')
#define PSL_ELLIPSE		((int)'e')
#define PSL_OCTAGON		((int)'g')
#define PSL_HEXAGON		((int)'h')
#define PSL_INVTRIANGLE		((int)'i')
#define PSL_ROTRECT		((int)'j')
#define PSL_MARC		((int)'m')
#define PSL_PENTAGON		((int)'n')
#define PSL_DOT			((int)'p')
#define PSL_RECT		((int)'r')
#define PSL_RNDRECT		((int)'R')
#define PSL_SQUARE		((int)'s')
#define PSL_TRIANGLE		((int)'t')
#define PSL_VECTOR		((int)'v')
#define PSL_WEDGE		((int)'w')
#define PSL_CROSS		((int)'x')
#define PSL_YDASH		((int)'y')
#define PSL_PLUS		((int)'+')
#define PSL_XDASH		((int)'-')

/* PSL codes for vector attributes */

#define BIT(no)		((unsigned int)(1 << (no)))

enum PSL_enum_vecattr {
	PSL_VEC_ARROW		= 0,		/* Default head symbol is arrow */
	PSL_VEC_TERMINAL	= 1,		/* Cross-bar normal to vector */
	PSL_VEC_CIRCLE		= 2,		/* Circle as vector head */
	PSL_VEC_SQUARE		= 3,		/* Square as vector head */
	PSL_VEC_TAIL		= 4,		/* Vector tail */
	PSL_VEC_ARROW_PLAIN	= 5,		/* Stylized vector head (just triangle lines; cannot be filled) */
	PSL_VEC_TAIL_PLAIN	= 6,		/* Stylized vector tail (just inward triangle lines; cannot be filled) */
	PSL_VEC_BEGIN		= 1,		/* Place vector head at beginning of vector. Add PSL_VEC_BEGIN_L for left only, PSL_VEC_BEGIN_R for right only */
	PSL_VEC_END			= 2,		/* Place vector head at end of vector.  Add PSL_VEC_END_L for left only, and PSL_VEC_END_R for right only */
	PSL_VEC_HEADS		= 3,		/* Mask for either head end */
	PSL_VEC_BEGIN_L		= BIT(2),	/* Left-half head at beginning */
	PSL_VEC_BEGIN_R		= BIT(3),	/* Right-half head at beginning */
	PSL_VEC_END_L		= BIT(4),	/* Left-half head at end */
	PSL_VEC_END_R		= BIT(5),	/* Right-half head at end */
	PSL_VEC_JUST_B		= 0,		/* Align vector beginning at (x,y) */
	PSL_VEC_JUST_C		= BIT(6),	/* Align vector center at (x,y) */
	PSL_VEC_JUST_E		= BIT(7),	/* Align vector end at (x,y) */
	PSL_VEC_JUST_S		= BIT(8),	/* Align vector center at (x,y) */
	PSL_VEC_ANGLES		= BIT(9),	/* Got start/stop angles instead of az, length */
	PSL_VEC_POLE		= BIT(10),	/* Got pole of small/great circle */
	PSL_VEC_OUTLINE		= BIT(11),	/* Draw vector head outline using default pen */
	PSL_VEC_OUTLINE2	= BIT(12),	/* Draw vector head outline using supplied v_pen */
	PSL_VEC_FILL		= BIT(13),	/* Fill vector head using default fill */
	PSL_VEC_FILL2		= BIT(14),	/* Fill vector head using supplied v_fill) */
	PSL_VEC_MARC90		= BIT(15),	/* Matharc only: if angles subtend 90, draw straight angle symbol */
	PSL_VEC_OFF_BEGIN	= BIT(16),	/* Starting point of vector should be moved a distance along the line */
	PSL_VEC_OFF_END		= BIT(17),	/* End point of vector should be moved a distance along the line */
	PSL_VEC_MID_FWD		= BIT(18),	/* End point of vector should be moved a distance along the line */
	PSL_VEC_MID_BWD		= BIT(19),	/* End point of vector should be moved a distance along the line */
	PSL_VEC_COMPONENTS	= BIT(20),	/* Not yet needed in postscriptlight: Got vector dx, dy Cartesian components */
	PSL_VEC_SCALE		= BIT(21),	/* Not yet needed in postscriptlight: If not set we determine the required inch-to-degree scale */
	PSL_VEC_LINE		= BIT(22),	/* Flag that we are adding vector heads to a line, not a stand-alone vector */
	PSL_VEC_MAGNIFY		= BIT(23),	/* Flag that we are adding vector heads to a line, not a stand-alone vector */
	PSL_VEC_FIXED		= BIT(24),	/* Flag that we were given a fixed length to override for each vector */
	PSL_VEC_MAGCPT		= BIT(25)};	/* Flag that says use user data magnitude as internal data for CPT lookup */

enum PSL_enum_vecdim {	/* Indices into the dim[] array passed to psl_vector */
	PSL_VEC_XTIP 			= 0,	/* x-coordinate of tip of vector in inches */
	PSL_VEC_YTIP 			= 1,	/* y-coordinate of tip of vector in inches */
	PSL_VEC_TAIL_WIDTH		= 2,	/* Width of tail stem (pen width) in inches */
	PSL_VEC_HEAD_LENGTH		= 3,	/* Length of the vector head in inches */
	PSL_VEC_HEAD_WIDTH		= 4,	/* Width of the vector head in inches */
	PSL_VEC_HEAD_SHAPE		= 5,	/* Shape (0-2) of the vector head */
	PSL_VEC_STATUS			= 6,	/* Sum of all vector bit flags */
	PSL_VEC_HEAD_TYPE_BEGIN	= 7,	/* Type of vector head at beginning of vector */
	PSL_VEC_HEAD_TYPE_END	= 8,	/* Type of vector head at end of vector */
	PSL_VEC_TRIM_BEGIN		= 9,	/* Amount of line trim at beginning of vector in inches*/
	PSL_VEC_TRIM_END		= 10,	/* Amount of line trim at end of vector in inches*/
	PSL_VEC_HEAD_PENWIDTH	= 11};	/* Pen width of vector head outline */

enum PSL_enum_wedgedim {	/* Indices into the dim[] array passed to psl_wedge */
	 PSL_WEDGE_RADIUS_O    = 0,	/* Outer radius of wedge in inches */
	 PSL_WEDGE_ANGLE_BEGIN = 1,	/* Begin angle in degrees */
	 PSL_WEDGE_ANGLE_END   = 2,	/* End angle in degrees */
	 PSL_WEDGE_STATUS      = 3,	/* Status bit flags */
	 PSL_WEDGE_RADIUS_I    = 4, 	/* Inner radius of wedge in inches */
	 PSL_WEDGE_DR          = 5, 	/* Radial increment in inches */
	 PSL_WEDGE_DA          = 6, 	/* Azimuthal increment in degrees */
	 PSL_WEDGE_ACTION      = 7 };	/* Sets filling (1) and/or outline (2) */

enum PSL_enum_matharcdim {	/* Indices into the dim[] array passed to psl_matharc */
	 PSL_MATHARC_RADIUS			= 0,	/* Radius of arc in inches */
	 PSL_MATHARC_ANGLE_BEGIN	= 1,	/* Begin angle in degrees */
	 PSL_MATHARC_ANGLE_END		= 2,	/* End angle in degrees */
	 PSL_MATHARC_HEAD_LENGTH	= 3,	/* Length of the vector head in inches */
	 PSL_MATHARC_HEAD_WIDTH		= 4,	/* Width of the vector head in inches */
	 PSL_MATHARC_ARC_PENWIDTH	= 5,	/* Pen width of arc in inches  */
	 PSL_MATHARC_HEAD_SHAPE		= 6,	/* Shape (0-2) of the vector head */
	 PSL_MATHARC_STATUS			= 7,	/* Sum of all vector bit flags */
	 PSL_MATHARC_HEAD_TYPE_BEGIN= 8,	/* Type of vector head at beginning of vector */
	 PSL_MATHARC_HEAD_TYPE_END	= 9,	/* Type of vector head at end of vector */
	 PSL_MATHARC_TRIM_BEGIN		= 10,	/* Amount of line trim at beginning of vector in degrees */
	 PSL_MATHARC_TRIM_END		= 11,	/* Amount of line trim at end of vector in degrees */
	 PSL_MATHARC_HEAD_PENWIDTH	= 12};	/* Pen width of vector head outline in inches  */

/* PSL macros for dealing with vector attributes */

#define PSL_vec_justify(status) ((status>>6)&3)			/* Return justification as 0-3 */
#define PSL_vec_head(status) ((status)&3)			/* Return head selection as 0-3 */
#define PSL_vec_side(status,head) (((status>>(2+2*head))&3) ? 2*((status>>(2+2*head))&3)-3 : 0)	/* Return side selection for this head as 0,-1,+1 */
#define PSL_vec_outline(status) ((status&PSL_VEC_OUTLINE) || (status&PSL_VEC_OUTLINE2))	/* Return true if outline is currently selected */
#define PSL_vec_fill(status) ((status&PSL_VEC_FILL) || (status&PSL_VEC_FILL2))		/* Return true if fill is currently selected */
#define PSL_vec_headcheck(status) (((status)&PSL_VEC_LINE) == 0)	/* Flag when vector head is actually the end point of a line so we should not consider length a factor to exclude heads */

/* PSL codes for arguments of PSL_beginplot and other routines */

enum PSL_enum_const {PSL_CM	= 0,
	PSL_INCH		= 1,
	PSL_METER		= 2,
	PSL_PT			= 3,
	PSL_BEGIN		= 0,
	PSL_END			= 1,
	PSL_FINALIZE		= 1,
	PSL_OVERLAY		= 1,
	PSL_MEMORY		= 2,
	PSL_CHANGESET		= 4,
	PSL_MEM_ALLOC		= 2097152, /* 2 Mb of memory */
	PSL_INIT		= 0,
	PSL_LANDSCAPE		= 0,
	PSL_PORTRAIT		= 1,
	PSL_ASCII85		= 0,
	PSL_HEX			= 1,
	PSL_NONE		= 0,
	PSL_RLE			= 1,
	PSL_LZW			= 2,
	PSL_DEFLATE		= 3,
	PSL_EO_CLIP		= 4,
	PSL_NO			= 0,
	PSL_YES			= 1,
	PSL_FWD			= 0,
	PSL_INV			= 1,
	PSL_OUTLINE		= 1,
	PSL_LINEAR		= 0,
	PSL_BEZIER		= 1,
	PSL_FILL_TRANSP		= 0,
	PSL_PEN_TRANSP		= 1,
	PSL_MAX_EPS_FONTS	= 6,
	PSL_MAX_DIMS		= 13,		/* Max number of dim arguments to PSL_plot_symbol */
	PSL_N_PATTERNS		= 91,		/* Current number of predefined patterns + 1, # 91 is user-supplied */
	PSL_FONTNAME_LEN	= 64,		/* Max length of font names */
	PSL_BUFSIZ		= 4096U};

/* PSL codes for pen movements (used by PSL_plotpoint, PSL_plotline, PSL_plotarc) */

enum PSL_enum_move {PSL_DRAW	= 0,
	PSL_MOVE		= 1,
	PSL_STROKE		= 2,
	PSL_REL			= 4,
	PSL_CLOSE		= 8,
	PSL_CLIP		= 16};

/* PSL codes for text and paragraph justification */

enum PSL_enum_just {PSL_BL	= 1,
	PSL_BC			= 2,
	PSL_BR			= 3,
	PSL_ML			= 5,
	PSL_MC			= 6,
	PSL_MR			= 7,
	PSL_TL			= 9,
	PSL_TC			= 10,
	PSL_TR			= 11,
	PSL_NO_DEF		= 12,
	PSL_JUST		= 4};

/* PSL code for rectangle shapes */

enum PSL_enum_rect {PSL_RECT_STRAIGHT	= 0,
	PSL_RECT_ROUNDED,
	PSL_RECT_CONVEX,
	PSL_RECT_CONCAVE};

/* PSL codes for line settings */

enum PSL_enum_line {PSL_BUTT_CAP	= 0,
	PSL_ROUND_CAP			= 1,
	PSL_SQUARE_CAP			= 2,
	PSL_MITER_JOIN			= 0,
	PSL_ROUND_JOIN			= 1,
	PSL_BEVEL_JOIN			= 2,
	PSL_MITER_DEFAULT		= 35};

/* PSL codes for text clipping (PSL_plottextline) */

enum PSL_enum_txt {PSL_TXT_INIT	= 1,
	PSL_TXT_SHOW		= 2,
	PSL_TXT_CLIP_ON		= 4,
	PSL_TXT_DRAW		= 8,
	PSL_TXT_CLIP_OFF	= 16,
	PSL_TXT_ROUND		= 32,
	PSL_TXT_CURVED		= 64,
	PSL_TXT_FILLBOX		= 128,
	PSL_TXT_DRAWBOX		= 256,
	PSL_TXT_FILLPEN		= 512,
	PSL_TXT_PENFILL		= 1024};

/* PSL codes for text hyphen substitution (PSL_settextmode) */

enum PSL_enum_txtmode {PSL_TXTMODE_HYPHEN	= 0,
	PSL_TXTMODE_MINUS			= 1};

/* Verbosity levels */

enum PSL_enum_verbose {
	PSL_MSG_QUIET = 0,		/* No messages whatsoever */
	PSL_MSG_ERROR,			/* Errors only */
	PSL_MSG_WARNING,		/* Warnings */
	PSL_MSG_TICTOC,			/* Tic-toc elapsed time message */
	PSL_MSG_INFORMATION,	/* Informational messages */
	PSL_MSG_COMPAT,			/* Compatibility warnings */
	PSL_MSG_DEBUG,			/* Debug messages */
	/* For API backwards compatibility only */
	PSL_MSG_NORMAL = 1,			/* Now PSL_MSG_ERROR */
	PSL_MSG_VERBOSE = 4,		/* Now PSL_MSG_WARNING */
	PSL_MSG_LONG_VERBOSE = 5	/* Now PSL_MSG_INFORMATION */
	};

/* Color spaces */

enum PSL_enum_color {PSL_RGB = 0,
	PSL_CMYK,
	PSL_HSV,
	PSL_GRAY};

/* Color types */

enum PSL_enum_fill {PSL_IS_STROKE = 0,
	PSL_IS_FILL,
	PSL_IS_FONT};

/* PSL error codes */

enum PSL_enum_err {PSL_BAD_VALUE = -99,	/* Bad value */
	PSL_BAD_JUST,		/* Bad text or paragraph justification */
	PSL_READ_FAILURE,	/* Read failure from a file */
	PSL_NO_POLYGON,		/* Less than 3 points */
	PSL_BAD_TEXT,		/* Text is too long */
	PSL_BAD_WIDTH,		/* Negative line width */
	PSL_NO_PATH,		/* Less than 2 points given as path */
	PSL_BAD_SYMBOL,		/* Unknown symbol type */
	PSL_BAD_SIZE,		/* Size is negative */
	PSL_BAD_RANGE,		/* Range defined by min/max exceeds limit */
	PSL_BAD_FLAG,		/* A flag is outside required range */
	PSL_NO_SESSION,		/* No active session */
	PSL_NO_ERROR = 0};	/* No errors, all is OK */

/* WHen we scan PostScript files to fine where the highres bounding box
 * start we know we have a line of a fixed length with plenty of space to
 * be rewritten without having to duplicate the entire file. As of now, we
 * enforce 64 characters for that line and use this amount to fseek back
 * to overwrite the highres line with actual values determined by gs. */
	
#define PSL_HIGHRES_LINE_LEN	64

/*--------------------------------------------------------------------
 *			PSL PARAMETERS DEFINITIONS
 *--------------------------------------------------------------------*/

struct PSL_FONT {	/* Definition */
	char name[PSL_FONTNAME_LEN];/* Name of this font */
	double height;		/* Height of A for unit fontsize */
	int encoded;		/* true if we never should re-encode this font (e.g. symbols) */
				/* This is also changed to true after we do re-encode a font */
	int encoded_orig;	/* The original setting that we can reset the array to */
};

struct PSL_CTRL {
	struct INIT {	/* Parameters set by user via PSL_beginplot() */
		FILE *err;			/* Error stream (NULL means stderr)		*/
		char *encoding;			/* The encoding name. e.g. ISO-8859-1		*/
		char *session;			/* The session name (NULL)			*/
		int runmode;			/* Nonzero if we are being called from a multi-module environment (0 for commandline)	*/
		int unit;			/* 0 = cm, 1 = inch, 2 = meter			*/
		int copies;			/* Number of copies for this plot		*/
		int layer_transp;		/* 0 = no layer transparency, 1 -t was used	*/
		double page_rgb[4];		/* RGB color for background paper [white]	*/
		double page_size[2];		/* Width and height of paper used in points	*/
		double magnify[2];		/* Global scale values [1/1]			*/
		double transparencies[2];	/* Current layer transparencies			*/
	} init;
	struct CURRENT {	/* Variables and settings that changes via PSL_* calls */
		char string[PSL_BUFSIZ];	/* Last text string plotted			*/
		char style[512];		/* Current setdash pattern			*/
		char bw_format[8];		/* Format used for grayshade value		*/
		char rgb_format[64];		/* Same, for RGB color triplets			*/
		char hsv_format[64];		/* Same, for HSV color triplets	(HSB in PS)	*/
		char cmyk_format[64];		/* Same, for CMYK color quadruples		*/
		char transparency_mode[16];	/* PDF transparency mode			*/
		double linewidth;		/* Current pen thickness			*/
		double rgb[3][4];		/* Current stroke, fill, and fs fill rgb	*/
		double offset;			/* Current setdash offset			*/
		double transparency;		/* Current transparency	[deprecated]		*/
		double transparencies[2];	/* Current transparencies			*/
		double fontsize;		/* Current font size				*/
		double subsupsize;		/* Fractional size of super/sub-scripts		*/
		double scapssize;		/* Fractional size of small caps		*/
		double sub_down;		/* Fractional fontsize shift down for subscript */
		double sup_up[2];		/* Fractional fontsize shift up for superscript */
						/* [0] is for lower-case, [1] is for uppercase  */
		int nclip;			/* Clip depth 					*/
		int font_no;			/* Current font number				*/
		int outline;			/* Current outline				*/
		int complete;			/* true for executing a custom PSL_plot_completion procedure once */
		int use_minus;			/* true for replacing hyphen code with minus codes */
	} current;
	struct INTERNAL {	/* Variables used internally only */
		char *SHAREDIR;			/* Pointer to path of directory with postscriptlight subdirectory */
		char *USERDIR;			/* Pointer to path of directory with user definitions */
		char *buffer;			/* Pointer to buffer where PS will be "written" when memory == 1 */
		char *user_image[PSL_N_PATTERNS];	/* Name of user patterns		*/
		char origin[2];			/* 'r', 'a', 'f', 'c' depending on reference for new origin x and y coordinate */
		double offset[2];		/* Origin offset [1/1]				*/
		double prev_offset[2];		/* Previous Origin offset [1/1]				*/
		double p_width;			/* Paper width in points, set in PSL_beginplot();	*/
		double p_height;		/* Paper height in points, set in PSL_beginplot();	*/
		double dpu;			/* PS dots per unit.  Must be set through PSL_beginplot();		*/
		double dpp;			/* PS dots per point.  Must be set through PSL_beginplot();		*/
		double x2ix;			/* Scales user x to PS dots			*/
		double y2iy;			/* Scales user y to PS dots			*/
		double p2u;			/* Scales dimensions in points (e.g., fonts, linewidths) to user units (e.g. inch)		*/
		double axis_limit[4];		/* The current xmin, xmax, ymin, ymax settings for axes */
		double axis_pos[2];		/* Lower left placement for axes		*/
		double axis_dim[2];		/* Lengths of axes 				*/
		int verbose;			/* Verbosity level (0-4): see PSL_MSG_*	*/
		int comments;			/* true for writing comments to output, false strips all comments */
		int overlay;			/* true if overlay (-O)				*/
		int landscape;			/* 1 = Landscape, 0 = Portrait		*/
		int memory;			/* 1 = write to memory, 0 = write to output	*/
		int text_init;			/* true after PSL_text.ps has been loaded	*/
		int image_format;		/* 0 writes images in ASCII, 2 uses binary	*/
		int N_FONTS;			/* Total no of fonts;  To add more, modify the file PSL_custom_fonts.txt */
		int compress;			/* Compresses images with (1) RLE or (2) LZW (3) DEFLATE or (0) None */
		int deflate_level; 		/* Compression level for DEFLATE (1-9, default 0) */
		int call_level; 		/* Level in a series of module calls from GMT */
		int color_mode;			/* 0 = rgb, 1 = cmyk, 2 = hsv (only 1-2 for images)	*/
		int line_cap;			/* 0, 1, or 2 for butt, round, or square [butt]	*/
		int line_join;			/* 0, 1, or 2 for miter, arc, or bevel [miter]	*/
		int miter_limit;		/* Acute angle threshold 0-180; 0 means PS default [0] */
		int ix, iy;			/* Absolute coordinates of last point		*/
		int n_userimages;		/* Number of specified custom patterns		*/
		int x0, y0;			/* x,y PS offsets				*/
		int pmode;			/* Mode of buffer plot (1 = has header, 2 = has trailer, 3 = both) */
		size_t n_alloc;			/* Allocation length of buffer			*/
		size_t n;			/* Length of buffer				*/
		FILE *fp;			/* PS output file pointer. NULL = stdout	*/
		struct PSL_FONT *font;		/* Pointer to array of font structures 		*/
		struct PSL_PATTERN {
			int nx, ny;	/* Dimension of pattern image */
			int status, depth, dpi;
			double f_rgb[4], b_rgb[4];
		} pattern[PSL_N_PATTERNS*2];
	} internal;
};

struct imageinfo {
	int magic;		/* magic number */
	int width;		/* width (pixels) of image */
	int height;		/* height (pixels) of image */
	int depth;		/* depth (1, 8, or 24 bits) of pixel; 0 for EPS */
	int length;		/* length (bytes) of image */
	int type;		/* type of file; see RT_* below */
	int maptype;	/* type of colormap; see RMT_* below */
	int maplength;	/* length (bytes) of following map */
	int xorigin;	/* x-coordinate of origin (EPS only) */
	int yorigin;	/* y-coordinate of origin (EPS only) */
	double llx, lly, trx, try; /* Four corners of the (HiRes)BoundingBox (EPS only) */
	/* color map follows for maplength bytes, followed by image */
};

#define	RAS_MAGIC	0x59a66a95	/* Magic number for Sun rasterfile */
#define EPS_MAGIC	0x25215053	/* Magic number for EPS file */
#define RT_OLD		0		/* Old-style, unencoded Sun rasterfile */
#define RT_STANDARD	1		/* Standard, unencoded Sun rasterfile */
#define RT_BYTE_ENCODED	2		/* Run-length-encoded Sun rasterfile */
#define RT_FORMAT_RGB	3		/* [X]RGB instead of [X]BGR Sun rasterfile */
#define RT_EPS		4		/* Encapsulated PostScript format */
#define RMT_NONE	0		/* maplength is expected to be 0 */
#define RMT_EQUAL_RGB	1		/* red[maplength/3], green[], blue[] follow */

/* Public functions */

EXTERN_MSC struct PSL_CTRL *New_PSL_Ctrl (char *session);
EXTERN_MSC int PSL_beginaxes (struct PSL_CTRL *PSL, double llx, double lly, double width, double height, double x0, double y0, double x1, double y1);
EXTERN_MSC int PSL_beginclipping (struct PSL_CTRL *PSL, double *x, double *y, int n, double rgb[], int flag);
EXTERN_MSC int PSL_beginlayer (struct PSL_CTRL *PSL, int layer);
EXTERN_MSC int PSL_beginplot (struct PSL_CTRL *PSL, FILE *fp, int orientation, int overlay, int color_mode, char origin[], double offset[], double page_size[], char *title, int font_no[]);
EXTERN_MSC int PSL_beginsession (struct PSL_CTRL *PSL, unsigned int search, char *sharedir, char *userdir);
EXTERN_MSC int PSL_copy (struct PSL_CTRL *PSL, const char *txt);
EXTERN_MSC int PSL_endaxes (struct PSL_CTRL *PSL);
EXTERN_MSC int PSL_endclipping (struct PSL_CTRL *PSL, int mode);
EXTERN_MSC int PSL_endlayer (struct PSL_CTRL *PSL);
EXTERN_MSC int PSL_endplot (struct PSL_CTRL *PSL, int lastpage);
EXTERN_MSC int PSL_endsession (struct PSL_CTRL *PSL);
EXTERN_MSC char * PSL_getplot (struct PSL_CTRL *PSL);
EXTERN_MSC char * PSL_makecolor (struct PSL_CTRL *PSL, double rgb[]);
EXTERN_MSC char * PSL_makefont (struct PSL_CTRL *PSL, double size, double rgb[]);
EXTERN_MSC char * PSL_makefontsize (struct PSL_CTRL *PSL, double size);
EXTERN_MSC char * PSL_makepen (struct PSL_CTRL *PSL, double linewidth, double rgb[], char *pattern, double offset);
EXTERN_MSC int PSL_plotarc (struct PSL_CTRL *PSL, double x, double y, double radius, double az1, double az2, int type);
EXTERN_MSC int PSL_plotaxis (struct PSL_CTRL *PSL, double annotation_int, char *label, double annotfontsize, int side);
EXTERN_MSC int PSL_plotbitimage (struct PSL_CTRL *PSL, double x, double y, double xsize, double ysize, int justify, unsigned char *buffer, int nx, int ny, double f_rgb[], double b_rgb[]);
EXTERN_MSC int PSL_plotcolorimage (struct PSL_CTRL *PSL, double x, double y, double xsize, double ysize, int justify, unsigned char *buffer, int nx, int ny, int nbits);
EXTERN_MSC int PSL_plotepsimage (struct PSL_CTRL *PSL, double x, double y, double xsize, double ysize, int justify, unsigned char *buffer, struct imageinfo *h);
EXTERN_MSC int PSL_plotlatexeps (struct PSL_CTRL *PSL, double x, double y, double xsize, double ysize, int justify, unsigned char *buffer, double *rgb, struct imageinfo *h);
EXTERN_MSC int PSL_plotline (struct PSL_CTRL *PSL, double *x, double *y, int n, int type);
EXTERN_MSC int PSL_plotcurve (struct PSL_CTRL *PSL, double *x, double *y, int n, int type);
EXTERN_MSC int PSL_plotparagraph (struct PSL_CTRL *PSL, double x, double y, double fontsize, char *paragraph, double angle, int justify);
EXTERN_MSC int PSL_plotparagraphbox (struct PSL_CTRL *PSL, double x, double y, double fontsize, char *paragraph, double angle, int justify, double offset[], int mode);
EXTERN_MSC int PSL_plotpoint (struct PSL_CTRL *PSL, double x, double y, int pen);
EXTERN_MSC int PSL_plotbox (struct PSL_CTRL *PSL, double x0, double y0, double x1, double y1);
EXTERN_MSC int PSL_plotpolygon (struct PSL_CTRL *PSL, double *x, double *y, int n);
EXTERN_MSC int PSL_plotsegment (struct PSL_CTRL *PSL, double x0, double y0, double x1, double y1);
EXTERN_MSC int PSL_plotsymbol (struct PSL_CTRL *PSL, double x, double y, double param[], int symbol);
EXTERN_MSC int PSL_plottext (struct PSL_CTRL *PSL, double x, double y, double fontsize, char *text, double angle, int justify, int mode);
EXTERN_MSC int PSL_plottextbox (struct PSL_CTRL *PSL, double x, double y, double fontsize, char *text, double angle, int justify, double offset[], int mode);
EXTERN_MSC int PSL_plottextline (struct PSL_CTRL *PSL, double x[], double y[], int np[], int n_segments, void *arg1, void *arg2, char *label[], double angle[], int nlabel_per_seg[], double fontsize, int justify, double offset[], int mode);
EXTERN_MSC int PSL_loadimage (struct PSL_CTRL *PSL, char *file, struct imageinfo *header, unsigned char **image);
EXTERN_MSC int PSL_loadeps (struct PSL_CTRL *PSL, char *file, struct imageinfo *h, unsigned char **picture);
EXTERN_MSC int PSL_setcolor (struct PSL_CTRL *PSL, double rgb[], int mode);
EXTERN_MSC int PSL_setcurrentpoint (struct PSL_CTRL *PSL, double x, double y);
EXTERN_MSC int PSL_setexec (struct PSL_CTRL *PSL, int action);
EXTERN_MSC int PSL_setdefaults (struct PSL_CTRL *PSL, double xyscales[], double page_rgb[], char *encoding);
EXTERN_MSC int PSL_setdash (struct PSL_CTRL *PSL, char *pattern, double offset);
EXTERN_MSC int PSL_setfill (struct PSL_CTRL *PSL, double rgb[], int outline);
EXTERN_MSC int PSL_setfont (struct PSL_CTRL *PSL, int font_no);
EXTERN_MSC int PSL_setrgb (struct PSL_CTRL *PSL, double rgb[]);
EXTERN_MSC int PSL_setfontdims (struct PSL_CTRL *PSL, double supsub, double scaps, double sup_lc, double sup_uc, double sdown);
EXTERN_MSC int PSL_setformat (struct PSL_CTRL *PSL, int n_decimals);
EXTERN_MSC int PSL_setimage (struct PSL_CTRL *PSL, int image_no, char *imagefile, unsigned char *image, int image_dpi, unsigned int dim[], double f_rgb[], double b_rgb[]);
EXTERN_MSC int PSL_setlinecap (struct PSL_CTRL *PSL, int cap);
EXTERN_MSC int PSL_setlinejoin (struct PSL_CTRL *PSL, int join);
EXTERN_MSC int PSL_setlinewidth (struct PSL_CTRL *PSL, double linewidth);
EXTERN_MSC int PSL_setmiterlimit (struct PSL_CTRL *PSL, int limit);
EXTERN_MSC int PSL_setorigin (struct PSL_CTRL *PSL, double x, double y, double angle, int mode);
EXTERN_MSC int PSL_setparagraph (struct PSL_CTRL *PSL, double line_space, double par_width, int par_just);
EXTERN_MSC int PSL_setpattern (struct PSL_CTRL *PSL, int image_no, char *imagefile, int image_dpi, double f_rgb[], double b_rgb[]);
EXTERN_MSC int PSL_settextmode (struct PSL_CTRL *PSL, int mode);
EXTERN_MSC int PSL_settransparencies (struct PSL_CTRL *PSL, double *transparencies);
EXTERN_MSC int PSL_settransparencymode (struct PSL_CTRL *PSL, const char *mode);
EXTERN_MSC int PSL_definteger (struct PSL_CTRL *PSL, const char *param, int value);
EXTERN_MSC int PSL_defpen (struct PSL_CTRL *PSL, const char *param, double width, char *style, double offset, double rgb[]);
EXTERN_MSC int PSL_defpoints (struct PSL_CTRL *PSL, const char *param, double fontsize);
EXTERN_MSC int PSL_defcolor (struct PSL_CTRL *PSL, const char *param, double rgb[]);
EXTERN_MSC int PSL_deftextdim (struct PSL_CTRL *PSL, const char *dim, double fontsize, char *text);
EXTERN_MSC int PSL_defunits (struct PSL_CTRL *PSL, const char *param, double value);

EXTERN_MSC unsigned char *psl_gray_encode (struct PSL_CTRL *PSL, size_t *nbytes, unsigned char *input);
EXTERN_MSC void psl_set_txt_array (struct PSL_CTRL *PSL, const char *param, char *array[], int n);
EXTERN_MSC void psl_set_int_array (struct PSL_CTRL *PSL, const char *param, int *array, int n);
EXTERN_MSC char *psl_prepare_text (struct PSL_CTRL *PSL, char *text);

/* Used indirectly by FORTRAN wrapper PSL_free_ . */
EXTERN_MSC int PSL_free_nonmacro (void *addr);

/* Definition for printing a message. When DEBUG is on, also print source file and line number.
 * Use this for various progress statements, debugging to see certain variables, and even fatal
 * error messages. */
/* For FORTRAN there is PSL_command_ that only accepts one text argument */
EXTERN_MSC int PSL_command (struct PSL_CTRL *C, const char *format, ...);
EXTERN_MSC int PSL_comment (struct PSL_CTRL *C, const char *format, ...);
EXTERN_MSC int PSL_initerr (struct PSL_CTRL *C, const char *format, ...);
EXTERN_MSC int PSL_message (struct PSL_CTRL *C, int level, const char *format, ...);
EXTERN_MSC FILE *PSL_fopen (struct PSL_CTRL *C, char *file, char *mode);
EXTERN_MSC int PSL_fclose (struct PSL_CTRL *C);

#ifdef PSL_WITH_GMT4_SUPPORT
/* Backwards compatible vector symbol from GMT 4 days */
EXTERN_MSC void psl_vector_v4 (struct PSL_CTRL *PSL, double x, double y, double param[], double rgb[], int outline);
#endif

/* Deprecated */
EXTERN_MSC int PSL_settransparency (struct PSL_CTRL *PSL, double transparency);

/*! Macro for free that explicitly checks for NULL pointer and sets freed pointer to NULL */
#define PSL_free(ptr) (free((void *)(ptr)),(ptr)=NULL)

#ifdef __cplusplus
}
#endif

#endif /* _POSTSCRIPTLIGHT_H */
