Blame term/pdf.trm

Packit 0986c0
/* Hello, Emacs, this is -*-C-*-
Packit 0986c0
 * $Id: pdf.trm,v 1.94 2014/05/07 04:37:28 sfeam Exp $
Packit 0986c0
 */
Packit 0986c0
Packit 0986c0
/*------------------------------
Packit 0986c0
	GNUPLOT - pdf.trm
Packit 0986c0
Packit 0986c0
	This file is included by ../term.c.
Packit 0986c0
Packit 0986c0
	This driver uses PDFlib from www.pdflib.com
Packit 0986c0
Packit 0986c0
	Author:
Packit 0986c0
Packit 0986c0
		Hans-Bernhard Br"oker
Packit 0986c0
		broeker@physik.rwth-aachen.de
Packit 0986c0
Packit 0986c0
	Licence: see the gnuplot copyright (to be merged into here...)
Packit 0986c0
Packit 0986c0
	Options: can #define PDF_DONT_COMPRESS to avoid PDF output
Packit 0986c0
	generated being compressed (by the 'deflate' algorithm as used
Packit 0986c0
	in 'zip' or 'gzip'). That helps in debugging.
Packit 0986c0
Packit 0986c0
------------------------------*/
Packit 0986c0
Packit 0986c0
/* CODEME: Add patterned lines (?). */
Packit 0986c0
Packit 0986c0
/* PM3D support by Johannes Zellner <johannes@zellner.org>, May-15-2002 */
Packit 0986c0
/* set_color fixes by Petr Mikulik <mikulik@physics.muni.cz>, June-10-2002 */
Packit 0986c0
/* image support by Ethan A Merritt <merritt@u.washington.edu>, March 2003 */
Packit 0986c0
Packit 0986c0
/* Text rotation 24-Jul-2002 Ethan A Merritt <merritt@u.washington.edu> */
Packit 0986c0
/* Revised fill patterns 02-Apr-2003 Ethan A Merritt */
Packit 0986c0
/* Enhanced text mode support November 2003 Ethan A Merritt */
Packit 0986c0
Packit 0986c0
#include "driver.h"
Packit 0986c0
Packit 0986c0
#ifdef TERM_REGISTER
Packit 0986c0
register_term(pdf)
Packit 0986c0
#endif
Packit 0986c0
Packit 0986c0
#ifdef TERM_PROTO
Packit 0986c0
TERM_PUBLIC void PDF_options __PROTO ((void));
Packit 0986c0
TERM_PUBLIC void PDF_init __PROTO ((void));
Packit 0986c0
TERM_PUBLIC void PDF_graphics __PROTO ((void));
Packit 0986c0
TERM_PUBLIC void PDF_text __PROTO ((void));
Packit 0986c0
TERM_PUBLIC void PDF_linetype __PROTO ((int linetype));
Packit 0986c0
TERM_PUBLIC void PDF_move __PROTO ((unsigned int x, unsigned int y));
Packit 0986c0
TERM_PUBLIC void PDF_vector __PROTO ((unsigned int x, unsigned int y));
Packit 0986c0
TERM_PUBLIC void PDF_put_text __PROTO ((unsigned int x, unsigned int y, const char *str));
Packit 0986c0
TERM_PUBLIC void PDF_reset __PROTO ((void));
Packit 0986c0
TERM_PUBLIC int PDF_justify_text __PROTO ((enum JUSTIFY mode));
Packit 0986c0
TERM_PUBLIC int PDF_text_angle __PROTO ((int ang));
Packit 0986c0
TERM_PUBLIC void PDF_point __PROTO ((unsigned int x, unsigned int y, int pointstyle));
Packit 0986c0
TERM_PUBLIC int PDF_set_font __PROTO ((const char *font));
Packit 0986c0
TERM_PUBLIC void PDF_boxfill __PROTO((int style, unsigned int x1, unsigned int y1, unsigned int width, unsigned int height));
Packit 0986c0
TERM_PUBLIC void PDF_linewidth __PROTO ((double linewidth));
Packit 0986c0
TERM_PUBLIC int PDF_make_palette __PROTO((t_sm_palette *));
Packit 0986c0
TERM_PUBLIC void PDF_previous_palette __PROTO((void));
Packit 0986c0
TERM_PUBLIC void PDF_set_color __PROTO((t_colorspec *));
Packit 0986c0
TERM_PUBLIC void PDF_image __PROTO((unsigned int, unsigned int, coordval *, gpiPoint *, t_imagecolor));
Packit 0986c0
Packit 0986c0
TERM_PUBLIC void PDF_filled_polygon __PROTO((int, gpiPoint *));
Packit 0986c0
Packit 0986c0
/* To support "set term png enhanced" */
Packit 0986c0
TERM_PUBLIC void ENHPDF_put_text __PROTO((unsigned int x, unsigned int y, const char *str));
Packit 0986c0
TERM_PUBLIC void ENHPDF_OPEN __PROTO((char * fontname, double fontsize,
Packit 0986c0
			double base, TBOOLEAN widthflag, TBOOLEAN showflag,
Packit 0986c0
			int overprint));
Packit 0986c0
TERM_PUBLIC void ENHPDF_FLUSH __PROTO((void));
Packit 0986c0
Packit 0986c0
#define PDF_NUM_POINTTYPES 75	/* number of point symbol types not counting the dot */
Packit 0986c0
Packit 0986c0
#define PDF_RESOLUTION  (20)	/* number of terminal pixels per pt */
Packit 0986c0
#define PDF_XMAX	(5*72*PDF_RESOLUTION) /* 5 inches, 72 pt/inch */
Packit 0986c0
#define PDF_YMAX	(3*72*PDF_RESOLUTION) /* 3 inches, 72 pt/inch */
Packit 0986c0
Packit 0986c0
static TBOOLEAN pdf_explicit_size = FALSE;
Packit 0986c0
static size_units pdf_explicit_units = INCHES;
Packit 0986c0
Packit 0986c0
#endif /* TERM_PROTO */
Packit 0986c0
Packit 0986c0
#ifndef TERM_PROTO_ONLY
Packit 0986c0
#ifdef TERM_BODY
Packit 0986c0
Packit 0986c0
#include <pdflib.h>
Packit 0986c0
Packit 0986c0
static PDF *myPDF = NULL;
Packit 0986c0
Packit 0986c0
static unsigned int PDF_xLast = UINT_MAX; /* current pen horizontal position*/
Packit 0986c0
static unsigned int PDF_yLast = UINT_MAX; /* current pen vertical position*/
Packit 0986c0
Packit 0986c0
static int PDF_LineType = LT_UNDEFINED;		/* current line type*/
Packit 0986c0
static int PDF_LineCap = 0;			/* Butt ends */
Packit 0986c0
static double PDF_LineWidth = 1.0;		/* current line width*/
Packit 0986c0
static int PDF_TextAngle = 0;			/* current text orientation*/
Packit 0986c0
static enum JUSTIFY PDF_TextJust = LEFT;	/* current text justification*/
Packit 0986c0
static double PDF_linewidth_factor = 1.0;	/* multiplier for line width */
Packit 0986c0
static double PDF_dashlength_factor = 1.0;	/* multiplier for dash length */
Packit 0986c0
static TBOOLEAN PDF_monochrome = FALSE;		/* default all linetypes to black */
Packit 0986c0
static rgb_color PDF_current_rgb = {0.,0.,0.};	/* Last color set */
Packit 0986c0
static double PDF_current_gray = 0.0;		/* Last color set (mono version) */
Packit 0986c0
Packit 0986c0
#ifdef HAVE_NODASH_LIBPDF
Packit 0986c0
static TBOOLEAN PDF_dashedlines = FALSE;	/* solid or dashed? */
Packit 0986c0
#else
Packit 0986c0
static TBOOLEAN PDF_dashedlines = TRUE;		/* solid or dashed? */
Packit 0986c0
#endif
Packit 0986c0
Packit 0986c0
/* default text font family: */
Packit 0986c0
static char PDF_fontNameDef[MAX_ID_LEN + 1] = "Helvetica";
Packit 0986c0
static double PDF_fontSizeDef = 6;	/* default text size*/
Packit 0986c0
/* current text font family: */
Packit 0986c0
static char PDF_fontNameCur[MAX_ID_LEN + 1] = "Helvetica";
Packit 0986c0
static double PDF_fontSizeCur = 6; /* current text size*/
Packit 0986c0
static double PDF_fontscale = 1.0;
Packit 0986c0
Packit 0986c0
static TBOOLEAN PDF_pageIsOpen = FALSE; /* already started a page ?? */
Packit 0986c0
static TBOOLEAN PDF_pathIsOpen = FALSE; /* open path flag*/
Packit 0986c0
Packit 0986c0
static int PDF_fontAscent = 0;	/* estimated current font ascent*/
Packit 0986c0
static int PDF_fontDescent = 0;	/* estimated current font descent*/
Packit 0986c0
static int PDF_fontLeading = 0;	/* estimated current font leading*/
Packit 0986c0
static int PDF_fontAvWidth = 0;	/* estimated current font char average width*/
Packit 0986c0
static int PDF_currentFontHandle; /* Needed for exhanced text mode */
Packit 0986c0
Packit 0986c0
static short PDF_Pen_RealID __PROTO ((int));
Packit 0986c0
static void PDF_PathOpen __PROTO ((void));
Packit 0986c0
static void PDF_PathClose __PROTO ((void));
Packit 0986c0
static void PDF_SetFont __PROTO ((void));
Packit 0986c0
static void PDF_DefinePatterns __PROTO((void));
Packit 0986c0
enum { PDF_patterns = 7 };
Packit 0986c0
static int PDF_patternHandles[PDF_patterns];
Packit 0986c0
Packit 0986c0
#ifndef HAVE_NODASH_LIBPDF
Packit 0986c0
/* Description of dash patterns (same as those in post.trm) */
Packit 0986c0
static int dash1[] = {8, 8};
Packit 0986c0
static int dash2[] = {4, 6};
Packit 0986c0
static int dash3[] = {2, 3};
Packit 0986c0
static int dash4[] = {12, 4, 2, 4};
Packit 0986c0
static int dash5[] = {6, 6, 2, 6};
Packit 0986c0
static int dash6[] = {4, 4, 4, 12};
Packit 0986c0
static int dash7[] = {1, 4, 12, 4, 1, 4};
Packit 0986c0
#endif
Packit 0986c0
Packit 0986c0
/*------------------------ helper functions -------------------*/
Packit 0986c0
Packit 0986c0
static short
Packit 0986c0
PDF_Pen_RealID (int inPenCode)
Packit 0986c0
{
Packit 0986c0
    if (inPenCode >= 12)
Packit 0986c0
	inPenCode %= 12;	/* normalize pen code*/
Packit 0986c0
    if (inPenCode <= LT_NODRAW)
Packit 0986c0
	inPenCode = LT_NODRAW;
Packit 0986c0
Packit 0986c0
    return (inPenCode + 2);
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
/* Functions to ensure that as many move() and vector() calls as
Packit 0986c0
 * possible get converted into a single long 'path', before closing it
Packit 0986c0
 * with a stroke or similar command. */
Packit 0986c0
static void
Packit 0986c0
PDF_PathOpen ()
Packit 0986c0
{
Packit 0986c0
    PDF_pathIsOpen = TRUE;
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
static void
Packit 0986c0
PDF_PathClose ()
Packit 0986c0
{
Packit 0986c0
    if (PDF_pathIsOpen) {
Packit 0986c0
	PDF_stroke(myPDF);
Packit 0986c0
Packit 0986c0
	PDF_pathIsOpen = FALSE;
Packit 0986c0
    }
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
/* Helper function to deal with switching over to a newly selected font.
Packit 0986c0
 * For now, this does not try to embed fonts into the PDF file.
Packit 0986c0
 * We would like to allow UTF-8 fonts via
Packit 0986c0
	font_handle = PDF_findfont(myPDF, PDF_fontNameCur, "unicode", 0);
Packit 0986c0
 * but this is not supported by the free-as-in-beer PDFlib Lite.
Packit 0986c0
 */
Packit 0986c0
static void
Packit 0986c0
PDF_SetFont ()
Packit 0986c0
{
Packit 0986c0
    int font_handle;
Packit 0986c0
    const char *pdfenc = "host";
Packit 0986c0
Packit 0986c0
    /* Allow graceful failure */
Packit 0986c0
    PDF_set_parameter(myPDF, "fontwarning", "false");
Packit 0986c0
Packit 0986c0
    /* LCB : Symbol and ZapfDingbats should use "builtin" encoding */
Packit 0986c0
    if ( (strcmp(PDF_fontNameCur,"Symbol") == 0) ||
Packit 0986c0
	 (strcmp(PDF_fontNameCur,"ZapfDingbats") == 0) ) {
Packit 0986c0
	pdfenc = "builtin";
Packit 0986c0
    } else if (encoding == S_ENC_ISO8859_1) {
Packit 0986c0
        pdfenc = "iso8859-1";
Packit 0986c0
    } else if (encoding == S_ENC_ISO8859_2) {
Packit 0986c0
        pdfenc = "iso8859-2";
Packit 0986c0
    } else if (encoding == S_ENC_ISO8859_9) {
Packit 0986c0
        pdfenc = "iso8859-9";
Packit 0986c0
    } else if (encoding == S_ENC_ISO8859_15) {
Packit 0986c0
        pdfenc = "iso8859-15";
Packit 0986c0
    } else if (encoding == S_ENC_CP1250) {
Packit 0986c0
        pdfenc = "cp1250";
Packit 0986c0
    } else if (encoding == S_ENC_CP1252) {
Packit 0986c0
        pdfenc = "cp1252";
Packit 0986c0
    }
Packit 0986c0
        
Packit 0986c0
    font_handle = PDF_findfont(myPDF, PDF_fontNameCur, pdfenc, 0);
Packit 0986c0
    
Packit 0986c0
    if (font_handle == -1 && strcmp(pdfenc, "host")) {
Packit 0986c0
        fprintf(stderr,"Couldn't find font %s in encoding %s, trying \"host\"\n", 
Packit 0986c0
	        PDF_fontNameCur, pdfenc);
Packit 0986c0
	font_handle = PDF_findfont(myPDF, PDF_fontNameCur, "host", 0);
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    if (font_handle == -1) {
Packit 0986c0
	font_handle = PDF_findfont(myPDF, "Times-Roman", "host", 0);
Packit 0986c0
	fprintf(stderr,"Couldn't find font %s, falling back to Times-Roman\n", PDF_fontNameCur);
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    PDF_setfont(myPDF, font_handle, PDF_fontSizeCur * PDF_RESOLUTION * PDF_fontscale);
Packit 0986c0
Packit 0986c0
    /* Ask PDFlib for the actual numbers */
Packit 0986c0
    PDF_fontAscent = (int) (PDF_RESOLUTION * PDF_fontSizeCur * PDF_fontscale * PDF_get_value(myPDF, "ascender", 0));
Packit 0986c0
    PDF_fontDescent = (int) (- PDF_RESOLUTION * PDF_fontSizeCur * PDF_fontscale * PDF_get_value(myPDF, "descender", 0));
Packit 0986c0
    PDF_fontLeading = (int) (PDF_RESOLUTION * PDF_fontSizeCur * PDF_fontscale * 0.25);
Packit 0986c0
Packit 0986c0
    /* Assume this particular string is a somewhat reasonable typical
Packit 0986c0
     * output, for getting at the average character width */
Packit 0986c0
    PDF_fontAvWidth = (int)
Packit 0986c0
	(PDF_RESOLUTION * PDF_stringwidth(myPDF, "01234567890123456789",
Packit 0986c0
					  font_handle, PDF_fontSizeCur * PDF_fontscale )
Packit 0986c0
	 / 20.0);
Packit 0986c0
    PDF_currentFontHandle = font_handle;
Packit 0986c0
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
#if !HAVE_OLD_LIBPDF
Packit 0986c0
static void
Packit 0986c0
PDF_DefinePatterns()
Packit 0986c0
{
Packit 0986c0
    int i;
Packit 0986c0
Packit 0986c0
    /* EAM April 2003 - Rearrange patterns to maximize contrast in mono.
Packit 0986c0
     * Because of the finite linewidth, each pattern must include line
Packit 0986c0
     * fragments at the "empty" corners.
Packit 0986c0
     */
Packit 0986c0
    for (i=0; i
Packit 0986c0
	PDF_patternHandles[i] = PDF_begin_pattern(myPDF, 8, 8, 8, 8, 2);
Packit 0986c0
	PDF_setlinewidth(myPDF, 0.25);
Packit 0986c0
	PDF_setlinecap(myPDF, 2); /* square ends */
Packit 0986c0
	switch (i) {
Packit 0986c0
	case 0:	PDF_moveto(myPDF, 0, 8);
Packit 0986c0
		PDF_lineto(myPDF, 8, 0);
Packit 0986c0
		PDF_moveto(myPDF, 0, 0);
Packit 0986c0
		PDF_lineto(myPDF, 8, 8);
Packit 0986c0
		PDF_stroke(myPDF);
Packit 0986c0
		break;
Packit 0986c0
	case 1:	PDF_moveto(myPDF, 0, 8);
Packit 0986c0
		PDF_lineto(myPDF, 8, 0);
Packit 0986c0
		PDF_moveto(myPDF, 0, 0);
Packit 0986c0
		PDF_lineto(myPDF, 8, 8);
Packit 0986c0
		PDF_moveto(myPDF, 4, 0);
Packit 0986c0
		PDF_lineto(myPDF, 8, 4);
Packit 0986c0
		PDF_lineto(myPDF, 4, 8);
Packit 0986c0
		PDF_lineto(myPDF, 0, 4);
Packit 0986c0
		PDF_lineto(myPDF, 4, 0);
Packit 0986c0
		PDF_stroke(myPDF);
Packit 0986c0
		break;
Packit 0986c0
	case 2:	PDF_moveto(myPDF, 0, 0);
Packit 0986c0
		PDF_lineto(myPDF, 0, 8);
Packit 0986c0
		PDF_lineto(myPDF, 8, 8);
Packit 0986c0
		PDF_lineto(myPDF, 8, 0);
Packit 0986c0
		PDF_lineto(myPDF, 0, 0);
Packit 0986c0
		PDF_fill(myPDF);
Packit 0986c0
		break;
Packit 0986c0
	case 3:	PDF_moveto(myPDF, 0, 4);
Packit 0986c0
		PDF_lineto(myPDF, 4, 0);
Packit 0986c0
		PDF_moveto(myPDF, 4, 8);
Packit 0986c0
		PDF_lineto(myPDF, 8, 4);
Packit 0986c0
		PDF_stroke(myPDF);
Packit 0986c0
		break;
Packit 0986c0
	case 4:	PDF_moveto(myPDF, 0, 4);
Packit 0986c0
		PDF_lineto(myPDF, 4, 8);
Packit 0986c0
		PDF_moveto(myPDF, 4, 0);
Packit 0986c0
		PDF_lineto(myPDF, 8, 4);
Packit 0986c0
		PDF_stroke(myPDF);
Packit 0986c0
		break;
Packit 0986c0
	case 5:	PDF_moveto(myPDF, 0, 4);
Packit 0986c0
		PDF_lineto(myPDF, 2, 0);
Packit 0986c0
		PDF_moveto(myPDF, 2, 8);
Packit 0986c0
		PDF_lineto(myPDF, 6, 0);
Packit 0986c0
		PDF_moveto(myPDF, 6, 8);
Packit 0986c0
		PDF_lineto(myPDF, 8, 4);
Packit 0986c0
		PDF_stroke(myPDF);
Packit 0986c0
		break;
Packit 0986c0
	case 6:	PDF_moveto(myPDF, 0, 4);
Packit 0986c0
		PDF_lineto(myPDF, 2, 8);
Packit 0986c0
		PDF_moveto(myPDF, 2, 0);
Packit 0986c0
		PDF_lineto(myPDF, 6, 8);
Packit 0986c0
		PDF_moveto(myPDF, 6, 0);
Packit 0986c0
		PDF_lineto(myPDF, 8, 4);
Packit 0986c0
		PDF_stroke(myPDF);
Packit 0986c0
		break;
Packit 0986c0
	case 7:	/* not used */
Packit 0986c0
		PDF_moveto(myPDF, 4, 0);
Packit 0986c0
		PDF_lineto(myPDF, 0, 2);
Packit 0986c0
		PDF_moveto(myPDF, 8, 2);
Packit 0986c0
		PDF_lineto(myPDF, 0, 6);
Packit 0986c0
		PDF_moveto(myPDF, 8, 6);
Packit 0986c0
		PDF_lineto(myPDF, 4, 8);
Packit 0986c0
		PDF_stroke(myPDF);
Packit 0986c0
		break;
Packit 0986c0
	case 8:	/* not used */
Packit 0986c0
		PDF_moveto(myPDF, 4, 0);
Packit 0986c0
		PDF_lineto(myPDF, 8, 2);
Packit 0986c0
		PDF_moveto(myPDF, 0, 2);
Packit 0986c0
		PDF_lineto(myPDF, 8, 6);
Packit 0986c0
		PDF_moveto(myPDF, 0, 6);
Packit 0986c0
		PDF_lineto(myPDF, 4, 8);
Packit 0986c0
		PDF_stroke(myPDF);
Packit 0986c0
		break;
Packit 0986c0
	}
Packit 0986c0
	PDF_end_pattern(myPDF);
Packit 0986c0
    }
Packit 0986c0
}
Packit 0986c0
#endif
Packit 0986c0
Packit 0986c0
/*------------------- the terminal entry functions --------------------*/
Packit 0986c0
Packit 0986c0
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
PDF_options ()
Packit 0986c0
{
Packit 0986c0
    /* Annoying hack to handle the case of 'set termoption' after */
Packit 0986c0
    /* we have already initialized the terminal.                  */
Packit 0986c0
    if (!almost_equals(c_token-1, "termopt$ion")) {
Packit 0986c0
	pdf_explicit_size = FALSE;
Packit 0986c0
	/* Default to enhanced text */
Packit 0986c0
	term->put_text = ENHPDF_put_text;
Packit 0986c0
	term->flags |= TERM_ENHANCED_TEXT;
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    while (!END_OF_COMMAND) {
Packit 0986c0
Packit 0986c0
	if (almost_equals(c_token, "enh$anced")) {
Packit 0986c0
	    c_token++;
Packit 0986c0
	    term->put_text = ENHPDF_put_text;
Packit 0986c0
	    term->flags |= TERM_ENHANCED_TEXT;
Packit 0986c0
	    continue;
Packit 0986c0
	} else if (almost_equals(c_token, "noenh$anced")) {
Packit 0986c0
	    c_token++;
Packit 0986c0
	    term->put_text = PDF_put_text;
Packit 0986c0
	    term->flags &= ~TERM_ENHANCED_TEXT;
Packit 0986c0
	    continue;
Packit 0986c0
	}
Packit 0986c0
Packit 0986c0
	if (almost_equals(c_token, "fn$ame") || almost_equals(c_token, "font"))  {
Packit 0986c0
	    char *s, *comma;
Packit 0986c0
	    c_token++;
Packit 0986c0
Packit 0986c0
	    if (!(s = try_to_get_string()))
Packit 0986c0
		int_error(c_token,"fname: expecting font name");
Packit 0986c0
	    comma = strrchr(s,',');
Packit 0986c0
	    if (comma && (1 == sscanf(comma+1,"%lf",&PDF_fontSizeDef)))
Packit 0986c0
		*comma = '\0';
Packit 0986c0
	    if (*s)
Packit 0986c0
		strncpy(PDF_fontNameDef, s, sizeof(PDF_fontNameDef));
Packit 0986c0
	    free(s);
Packit 0986c0
	    continue;
Packit 0986c0
	}
Packit 0986c0
Packit 0986c0
	if (almost_equals(c_token, "fs$ize")) {
Packit 0986c0
	    c_token++;
Packit 0986c0
Packit 0986c0
	    if (END_OF_COMMAND)
Packit 0986c0
		int_error(c_token,"fsize: expecting font size");
Packit 0986c0
	    PDF_fontSizeDef = real_expression();
Packit 0986c0
	    continue;
Packit 0986c0
	}
Packit 0986c0
Packit 0986c0
	if (equals(c_token, "lw") || almost_equals(c_token, "linew$idth")) {
Packit 0986c0
	    c_token++;
Packit 0986c0
Packit 0986c0
	    if (END_OF_COMMAND)
Packit 0986c0
		int_error(c_token, "expecting line width");
Packit 0986c0
	    PDF_linewidth_factor = real_expression();
Packit 0986c0
	    if (PDF_linewidth_factor <= 0)
Packit 0986c0
		PDF_linewidth_factor = 0.1;
Packit 0986c0
	    continue;
Packit 0986c0
	}
Packit 0986c0
Packit 0986c0
	if (almost_equals(c_token, "rou$nded")) {
Packit 0986c0
	    c_token++;
Packit 0986c0
	    PDF_LineCap = 1;
Packit 0986c0
	    continue;
Packit 0986c0
	}
Packit 0986c0
Packit 0986c0
	if (equals(c_token, "butt")) {
Packit 0986c0
	    PDF_LineCap = 0;
Packit 0986c0
	    continue;
Packit 0986c0
	}
Packit 0986c0
Packit 0986c0
	if (equals(c_token, "color") || almost_equals(c_token, "col$our")) {
Packit 0986c0
	    c_token++;
Packit 0986c0
	    PDF_monochrome = FALSE;
Packit 0986c0
	    term->flags &= ~TERM_MONOCHROME;
Packit 0986c0
	    continue;
Packit 0986c0
	}   
Packit 0986c0
Packit 0986c0
	if (almost_equals(c_token, "mono$chrome")) {
Packit 0986c0
	    c_token++;
Packit 0986c0
	    PDF_monochrome = TRUE;
Packit 0986c0
	    term->flags |= TERM_MONOCHROME;
Packit 0986c0
	    continue;
Packit 0986c0
	}   
Packit 0986c0
Packit 0986c0
	if (equals(c_token, "dl") || almost_equals(c_token, "dashl$ength")) {
Packit 0986c0
	    c_token++;
Packit 0986c0
	    if (END_OF_COMMAND)
Packit 0986c0
		int_error(c_token, "expecting dashlength multiplier");
Packit 0986c0
	    PDF_dashlength_factor = real_expression();
Packit 0986c0
	    if (PDF_dashlength_factor < 0.0)
Packit 0986c0
		PDF_dashlength_factor = 1.0;
Packit 0986c0
	    continue;
Packit 0986c0
	}
Packit 0986c0
Packit 0986c0
	if (almost_equals(c_token, "dash$ed") || equals(c_token, "solid")) {
Packit 0986c0
	    /* Version 5 always enables dashed lines */
Packit 0986c0
	    c_token++;
Packit 0986c0
	    continue;
Packit 0986c0
	}
Packit 0986c0
Packit 0986c0
	if (equals(c_token, "size")) {
Packit 0986c0
	    float xmax_t, ymax_t;
Packit 0986c0
	    c_token++;
Packit 0986c0
	    pdf_explicit_size = TRUE;
Packit 0986c0
	    pdf_explicit_units = parse_term_size(&xmax_t, &ymax_t, INCHES);
Packit 0986c0
	    term->xmax = xmax_t*PDF_RESOLUTION*72./gp_resolution;
Packit 0986c0
	    term->ymax = ymax_t*PDF_RESOLUTION*72./gp_resolution;
Packit 0986c0
	    continue;
Packit 0986c0
	}
Packit 0986c0
Packit 0986c0
	if (equals(c_token, "fontscale")) {
Packit 0986c0
	    c_token++;
Packit 0986c0
	    PDF_fontscale = END_OF_COMMAND ? -1 : real_expression();
Packit 0986c0
	    if (PDF_fontscale < 0)
Packit 0986c0
		PDF_fontscale = 1.0;
Packit 0986c0
	    continue;
Packit 0986c0
	}
Packit 0986c0
Packit 0986c0
	int_error(c_token, "unexpected text at end of command");
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    /* Save options back into options string in normalized format */
Packit 0986c0
    sprintf(term_options, "%s%s fname '%s'  fsize %g fontscale %3.1f linewidth %3.1f %s ",
Packit 0986c0
	    PDF_monochrome ? "monochrome " : " ",
Packit 0986c0
	    term->put_text == ENHPDF_put_text ? "enhanced" : "noenhanced",
Packit 0986c0
	    PDF_fontNameDef, PDF_fontSizeDef, PDF_fontscale, PDF_linewidth_factor,
Packit 0986c0
	    PDF_LineCap == 1 ? "rounded" : "");
Packit 0986c0
    if (PDF_dashedlines)
Packit 0986c0
	sprintf(&(term_options[strlen(term_options)]), "dl %3.1f",
Packit 0986c0
		PDF_dashlength_factor);
Packit 0986c0
    if (pdf_explicit_size) {
Packit 0986c0
	if (pdf_explicit_units == CM)
Packit 0986c0
	    sprintf(&(term_options[strlen(term_options)]), "size %.2fcm, %.2fcm ", 
Packit 0986c0
		2.54*(float)term->xmax/(72.*PDF_RESOLUTION),
Packit 0986c0
		2.54*(float)term->ymax/(72.*PDF_RESOLUTION));
Packit 0986c0
	else
Packit 0986c0
	    sprintf(&(term_options[strlen(term_options)]), "size %.2fin, %.2fin ", 
Packit 0986c0
		(float)term->xmax/(72.*PDF_RESOLUTION),
Packit 0986c0
		(float)term->ymax/(72.*PDF_RESOLUTION));
Packit 0986c0
    }
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
PDF_init ()
Packit 0986c0
{
Packit 0986c0
    static TBOOLEAN PDFlib_booted = FALSE;
Packit 0986c0
    char *gpversionstring;
Packit 0986c0
    char *username;
Packit 0986c0
    char *timedate;
Packit 0986c0
    time_t now;
Packit 0986c0
Packit 0986c0
    if (!PDFlib_booted) {
Packit 0986c0
	PDF_boot();
Packit 0986c0
	PDFlib_booted = TRUE;
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    if (!myPDF)
Packit 0986c0
	myPDF = PDF_new();
Packit 0986c0
Packit 0986c0
    /*open new PDF file */
Packit 0986c0
#ifdef HAVE_LIBPDF_OPEN_FILE
Packit 0986c0
    if (PDF_open_file(myPDF, outstr) == -1)
Packit 0986c0
#else
Packit 0986c0
    if (PDF_begin_document(myPDF, outstr?outstr:"-", 0,
Packit 0986c0
			   "compatibility=1.4") == -1)
Packit 0986c0
#endif /* HAVE_LIBPDF_OPEN_FILE */
Packit 0986c0
	int_error(NO_CARET, "Error:cannot open PDF file .\n");
Packit 0986c0
Packit 0986c0
#ifdef PDF_DONT_COMPRESS
Packit 0986c0
    /* for easier debugging of the output, turn off PDF stream
Packit 0986c0
     * compression */
Packit 0986c0
    PDF_set_value(myPDF, "compress", 0);
Packit 0986c0
#endif
Packit 0986c0
Packit 0986c0
    gpversionstring = gp_alloc(20 + strlen(gnuplot_version) + 
Packit 0986c0
			       strlen(gnuplot_patchlevel) + 1, "PDF_init");
Packit 0986c0
    sprintf(gpversionstring,"gnuplot %s patchlevel %s",
Packit 0986c0
	    gnuplot_version, gnuplot_patchlevel);
Packit 0986c0
Packit 0986c0
    time(&now;;
Packit 0986c0
    timedate=asctime(localtime(&now));
Packit 0986c0
    timedate[strlen(timedate)-1]='\0';
Packit 0986c0
Packit 0986c0
    PDF_set_info(myPDF,"Creator",gpversionstring);
Packit 0986c0
Packit 0986c0
    username=getusername();
Packit 0986c0
    if (username) {
Packit 0986c0
	PDF_set_info(myPDF,"Author",username);
Packit 0986c0
	free(username);
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    if (outstr)
Packit 0986c0
	PDF_set_info(myPDF,"Title",outstr); /* FIXME: use 'set title', if any? */
Packit 0986c0
    PDF_set_info(myPDF,"Subject","gnuplot plot");
Packit 0986c0
Packit 0986c0
    if (gpversionstring)
Packit 0986c0
	free(gpversionstring);
Packit 0986c0
Packit 0986c0
    PDF_LineType = LT_UNDEFINED;
Packit 0986c0
Packit 0986c0
    /* set current font to default */
Packit 0986c0
    strcpy(PDF_fontNameCur, PDF_fontNameDef);
Packit 0986c0
    PDF_fontSizeCur = PDF_fontSizeDef;
Packit 0986c0
Packit 0986c0
#if !HAVE_OLD_LIBPDF
Packit 0986c0
    PDF_DefinePatterns();
Packit 0986c0
#endif
Packit 0986c0
Packit 0986c0
    /* Have to start the first page now, in order to know the actual
Packit 0986c0
     * size of the selected font */
Packit 0986c0
    PDF_graphics();
Packit 0986c0
Packit 0986c0
    /* set h_char, v_char*/
Packit 0986c0
    term->h_char = PDF_fontAvWidth;
Packit 0986c0
    term->v_char = (PDF_fontAscent + PDF_fontDescent + PDF_fontLeading);
Packit 0986c0
Packit 0986c0
    /* set h_tic, v_tic*/
Packit 0986c0
    term->h_tic = term->v_tic = 3 * PDF_RESOLUTION;
Packit 0986c0
Packit 0986c0
    /* initialize terminal's pointsize from "set pointsize" value */
Packit 0986c0
    term_pointsize = pointsize;
Packit 0986c0
Packit 0986c0
    /* Initialize other default settings */
Packit 0986c0
    PDF_setlinecap(myPDF, PDF_LineCap);
Packit 0986c0
    PDF_setlinejoin(myPDF, PDF_LineCap);	/* round+round or butt+mitre */
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
PDF_graphics ()
Packit 0986c0
{
Packit 0986c0
    if (PDF_pageIsOpen)
Packit 0986c0
	return;			/* already open --> nothing to do */
Packit 0986c0
Packit 0986c0
    PDF_pathIsOpen = FALSE;
Packit 0986c0
    PDF_xLast = PDF_yLast = UINT_MAX;
Packit 0986c0
Packit 0986c0
    /* set size of canvas */
Packit 0986c0
    if (!pdf_explicit_size) {
Packit 0986c0
	term->xmax = PDF_XMAX;
Packit 0986c0
	term->ymax = PDF_YMAX;
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    PDF_begin_page(myPDF, (double)term->xmax / PDF_RESOLUTION,
Packit 0986c0
		   (double)term->ymax / PDF_RESOLUTION);
Packit 0986c0
    PDF_scale(myPDF, 1.0/PDF_RESOLUTION, 1.0/PDF_RESOLUTION);
Packit 0986c0
    if (title.text && title.text[0])
Packit 0986c0
	/* a title has been set --> use it as the bookmark name, too */
Packit 0986c0
	PDF_add_bookmark(myPDF, title.text, 0, 1);
Packit 0986c0
    PDF_pageIsOpen = TRUE;
Packit 0986c0
Packit 0986c0
    PDF_SetFont();
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
PDF_text ()
Packit 0986c0
{
Packit 0986c0
    PDF_PathClose();
Packit 0986c0
    PDF_end_page(myPDF);
Packit 0986c0
    PDF_pageIsOpen = FALSE;
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
PDF_reset ()
Packit 0986c0
{
Packit 0986c0
    assert(PDF_pageIsOpen == FALSE);
Packit 0986c0
#ifdef HAVE_LIBPDF_OPEN_FILE
Packit 0986c0
    PDF_close(myPDF);
Packit 0986c0
#else
Packit 0986c0
    PDF_end_document(myPDF, "");
Packit 0986c0
#endif /* HAVE_LIBPDF_OPEN_FILE */
Packit 0986c0
    PDF_delete(myPDF);
Packit 0986c0
    myPDF = NULL;
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
PDF_linetype (int linetype)
Packit 0986c0
{
Packit 0986c0
    int dash = linetype % 8;
Packit 0986c0
Packit 0986c0
    linetype = PDF_Pen_RealID(linetype);
Packit 0986c0
    if (linetype == PDF_LineType)
Packit 0986c0
	return;
Packit 0986c0
	
Packit 0986c0
    PDF_PathClose ();
Packit 0986c0
    PDF_LineType = linetype;
Packit 0986c0
Packit 0986c0
    if (PDF_monochrome) {
Packit 0986c0
	PDF_current_gray = 0.0;
Packit 0986c0
	PDF_setgray(myPDF, PDF_current_gray);
Packit 0986c0
    } else {
Packit 0986c0
	unsigned int irgb = pm3d_color_names_tbl[1+linetype].value;
Packit 0986c0
	PDF_current_rgb.r = (double)((irgb >> 16) & 0xff) / 255.;
Packit 0986c0
	PDF_current_rgb.g = (double)((irgb >>  8) & 0xff) / 255.;
Packit 0986c0
	PDF_current_rgb.b = (double)((irgb      ) & 0xff) / 255.;
Packit 0986c0
	PDF_setrgbcolor(myPDF, PDF_current_rgb.r, PDF_current_rgb.g, PDF_current_rgb.b);
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
#ifndef HAVE_NODASH_LIBPDF
Packit 0986c0
	if (PDF_dashedlines) {
Packit 0986c0
	    char dashtype[64];
Packit 0986c0
	    float dl = 8.0 * PDF_dashlength_factor;
Packit 0986c0
Packit 0986c0
	    switch (dash) {
Packit 0986c0
	    default:
Packit 0986c0
	    case 0:	PDF_setdash(myPDF, 0.0, 0.0);
Packit 0986c0
			return;
Packit 0986c0
	    case 1:	sprintf(dashtype,"dasharray={%4.1f %4.1f}",
Packit 0986c0
			dl*dash1[0],dl*dash1[1]);
Packit 0986c0
			break;
Packit 0986c0
	    case 2:	sprintf(dashtype,"dasharray={%4.1f %4.1f}",
Packit 0986c0
			dl*dash2[0],dl*dash2[1]);
Packit 0986c0
			break;
Packit 0986c0
	    case 3:	sprintf(dashtype,"dasharray={%4.1f %4.1f}",
Packit 0986c0
			dl*dash3[0],dl*dash3[1]);
Packit 0986c0
			break;
Packit 0986c0
	    case 4:	sprintf(dashtype,"dasharray={%4.1f %4.1f %4.1f %4.1f}",
Packit 0986c0
			dl*dash4[0],dl*dash4[1],dl*dash4[2],dl*dash4[3]);
Packit 0986c0
			break;
Packit 0986c0
	    case 5:	sprintf(dashtype,"dasharray={%4.1f %4.1f %4.1f %4.1f}",
Packit 0986c0
			dl*dash5[0],dl*dash5[1],dl*dash5[2],dl*dash5[3]);
Packit 0986c0
			break;
Packit 0986c0
	    case 6:	sprintf(dashtype,"dasharray={%4.1f %4.1f %4.1f %4.1f}",
Packit 0986c0
			dl*dash6[0],dl*dash6[1],dl*dash6[2],dl*dash6[3]);
Packit 0986c0
			break;
Packit 0986c0
	    case 7:	sprintf(dashtype,"dasharray={%4.1f %4.1f %4.1f %4.1f %4.1f %4.1f}",
Packit 0986c0
			dl*dash7[0],dl*dash7[1],dl*dash7[2],dl*dash7[3],dl*dash7[4],dl*dash7[5]);
Packit 0986c0
			break;
Packit 0986c0
	    }
Packit 0986c0
	    PDF_setdashpattern(myPDF,dashtype);
Packit 0986c0
	}
Packit 0986c0
#endif
Packit 0986c0
	
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
PDF_linewidth (double linewidth)
Packit 0986c0
{
Packit 0986c0
    PDF_PathClose();
Packit 0986c0
    PDF_LineWidth = PDF_RESOLUTION * PDF_linewidth_factor * linewidth / 4.0;
Packit 0986c0
    if (PDF_LineWidth < 0.1)
Packit 0986c0
	PDF_LineWidth = 0.1;
Packit 0986c0
    PDF_setlinewidth(myPDF, PDF_LineWidth);
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
PDF_move (unsigned int x, unsigned int y)
Packit 0986c0
{
Packit 0986c0
    if (PDF_pathIsOpen && x == PDF_xLast && y == PDF_yLast)
Packit 0986c0
	return;
Packit 0986c0
Packit 0986c0
    PDF_PathOpen ();
Packit 0986c0
    PDF_moveto(myPDF, x, y);
Packit 0986c0
Packit 0986c0
    PDF_xLast = x;
Packit 0986c0
    PDF_yLast = y;
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
PDF_vector (unsigned int x, unsigned int y)
Packit 0986c0
{
Packit 0986c0
    if (PDF_pathIsOpen && x == PDF_xLast && y == PDF_yLast)
Packit 0986c0
	return;
Packit 0986c0
Packit 0986c0
    if (!PDF_pathIsOpen) {
Packit 0986c0
	PDF_PathOpen ();
Packit 0986c0
	PDF_moveto(myPDF, PDF_xLast, PDF_yLast);
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    PDF_lineto(myPDF, x, y);
Packit 0986c0
Packit 0986c0
    PDF_xLast = x;
Packit 0986c0
    PDF_yLast = y;
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
/* Helper function. Many symbols have an additional dot in their
Packit 0986c0
 * center, so isolate its drawing into a separate function. */
Packit 0986c0
static GP_INLINE void
Packit 0986c0
PDF_dot (unsigned int x, unsigned int y)
Packit 0986c0
{
Packit 0986c0
    /* Imitate PS's way of creating a small dot by a zero-length line
Packit 0986c0
     * segment with rounded endpoints */
Packit 0986c0
    PDF_setlinecap(myPDF, 1); /* rounded ends */
Packit 0986c0
    PDF_moveto(myPDF, x, y);
Packit 0986c0
    PDF_lineto(myPDF, x, y);
Packit 0986c0
    PDF_stroke(myPDF);
Packit 0986c0
    PDF_setlinecap(myPDF, PDF_LineCap); /* restore ends */
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
PDF_point (unsigned int x, unsigned int y, int number)
Packit 0986c0
{
Packit 0986c0
    PDF_PathClose ();
Packit 0986c0
    PDF_save(myPDF);
Packit 0986c0
Packit 0986c0
    if (number < 0 || term_pointsize <= 0) {
Packit 0986c0
	/* Treat all negative point sizes as  dots */
Packit 0986c0
	PDF_dot(x, y);
Packit 0986c0
    } else {
Packit 0986c0
	/* Change coordinate system so the point symbols themselves
Packit 0986c0
	 * can be drawn without depending on position or size (-->
Packit 0986c0
	 * better compression and less coding for gnuplot) */
Packit 0986c0
	/* NB: I use the do_pointsize() default implementation, which
Packit 0986c0
	 * just stores the last set pointsize into `term_pointsize',
Packit 0986c0
	 * to avoid introducing another static driver-local variable
Packit 0986c0
	 * */
Packit 0986c0
	PDF_translate(myPDF, x, y);
Packit 0986c0
	PDF_scale(myPDF, term->h_tic / 2.0 * term_pointsize,
Packit 0986c0
		  term->v_tic / 2.0 * term_pointsize);
Packit 0986c0
	/* Correct linewidth to counter the scaling effect --- assume
Packit 0986c0
	 * h_tic is usable, to avoid having to average h_ and v_tic */
Packit 0986c0
	PDF_setlinewidth(myPDF,
Packit 0986c0
			 PDF_LineWidth / (term->h_tic / 2.0 * term_pointsize));
Packit 0986c0
	switch (number %= PDF_NUM_POINTTYPES) {
Packit 0986c0
	case 0:			/* Plus */
Packit 0986c0
	    PDF_moveto(myPDF, -1, 0);
Packit 0986c0
	    PDF_lineto(myPDF, 1, 0);
Packit 0986c0
	    PDF_moveto(myPDF, 0, -1);
Packit 0986c0
	    PDF_lineto(myPDF, 0, 1);
Packit 0986c0
	    PDF_stroke(myPDF);
Packit 0986c0
	    break;
Packit 0986c0
	case 2:			/* Star */
Packit 0986c0
	    PDF_moveto(myPDF, -1, 0);
Packit 0986c0
	    PDF_lineto(myPDF, 1, 0);
Packit 0986c0
	    PDF_moveto(myPDF, 0, -1);
Packit 0986c0
	    PDF_lineto(myPDF, 0, 1);
Packit 0986c0
	    /* FALLTHROUGH */
Packit 0986c0
	case 1:			/* Cross */
Packit 0986c0
	    PDF_moveto(myPDF, -1, -1);
Packit 0986c0
	    PDF_lineto(myPDF, 1, 1);
Packit 0986c0
	    PDF_moveto(myPDF, 1, -1);
Packit 0986c0
	    PDF_lineto(myPDF, -1, 1);
Packit 0986c0
	    PDF_stroke(myPDF);
Packit 0986c0
	    break;
Packit 0986c0
Packit 0986c0
/* For each x = 0..5, 4 shapes are defined:
Packit 0986c0
 * 3 + 2*x --> hollow symbol with a dot at its center
Packit 0986c0
 * 4 + 2*x --> solid symbol filled in linetype's color
Packit 0986c0
 * 63 + x  --> hollow symbol without the center dot
Packit 0986c0
 * 69 + x  --> symbol filled with white --> opaque symbol */
Packit 0986c0
Packit 0986c0
	case 63+0:		/* BoxEmpty */
Packit 0986c0
	case 3+2*0:		/* Box */
Packit 0986c0
	    PDF_moveto(myPDF, -1, -1);
Packit 0986c0
	    PDF_lineto(myPDF, 1, -1);
Packit 0986c0
	    PDF_lineto(myPDF, 1, 1);
Packit 0986c0
	    PDF_lineto(myPDF, -1, 1);
Packit 0986c0
	    PDF_closepath_stroke(myPDF);
Packit 0986c0
	    if (number == 3) PDF_dot(0,0);
Packit 0986c0
	    break;
Packit 0986c0
	case 69+0:		/* BoxWhitefilled */
Packit 0986c0
	    PDF_setgray_fill(myPDF, 1);
Packit 0986c0
	    /* FALLTHROUGH */
Packit 0986c0
	case 4+2*0:		/* BoxFilled */
Packit 0986c0
	    PDF_moveto(myPDF, -1, -1);
Packit 0986c0
	    PDF_lineto(myPDF, 1, -1);
Packit 0986c0
	    PDF_lineto(myPDF, 1, 1);
Packit 0986c0
	    PDF_lineto(myPDF, -1, 1);
Packit 0986c0
	    PDF_closepath_fill_stroke(myPDF);
Packit 0986c0
	    break;
Packit 0986c0
Packit 0986c0
	case 63+1:		/* CircleEmpty */
Packit 0986c0
	case 3+2*1:		/* Circle */
Packit 0986c0
	    PDF_circle(myPDF, 0, 0, 1);
Packit 0986c0
	    PDF_stroke(myPDF);
Packit 0986c0
	    if (number == 5) PDF_dot(0,0);
Packit 0986c0
	    break;
Packit 0986c0
	case 69+1:		/* CircleWhitefilled */
Packit 0986c0
	    PDF_setgray_fill(myPDF, 1);
Packit 0986c0
	    /* FALLTHROUGH */
Packit 0986c0
	case 4+2*1:		/* CircleFilled */
Packit 0986c0
	    PDF_circle(myPDF, 0, 0, 1);
Packit 0986c0
	    PDF_fill_stroke(myPDF);
Packit 0986c0
	    break;
Packit 0986c0
Packit 0986c0
	case 63+2:		/* TriangleUpEmpty */
Packit 0986c0
	case 3+2*2:		/* TriangleUp */
Packit 0986c0
	    PDF_moveto(myPDF, 0, 1.12);
Packit 0986c0
	    PDF_lineto(myPDF, -1, -0.5);
Packit 0986c0
	    PDF_lineto(myPDF, 1, -0.5);
Packit 0986c0
	    PDF_closepath_stroke(myPDF);
Packit 0986c0
	    if (number == 7) PDF_dot(0,0);
Packit 0986c0
	    break;
Packit 0986c0
	case 69+2:		/* TriangleUpWhitefilled */
Packit 0986c0
	    PDF_setgray_fill(myPDF, 1);
Packit 0986c0
	    /* FALLTHROUGH */
Packit 0986c0
	case 4+2*2:			/* TriangleUpFilled */
Packit 0986c0
	    PDF_moveto(myPDF, 0, 1.12);
Packit 0986c0
	    PDF_lineto(myPDF, -1, -0.5);
Packit 0986c0
	    PDF_lineto(myPDF, 1, -0.5);
Packit 0986c0
	    PDF_closepath_fill_stroke(myPDF);
Packit 0986c0
	    break;
Packit 0986c0
Packit 0986c0
	case 63+3:		/* TriangleDownEmpty */
Packit 0986c0
	case 3+2*3:		/* TriangleDown */
Packit 0986c0
	    PDF_moveto(myPDF, 0, -1.12);
Packit 0986c0
	    PDF_lineto(myPDF, -1, 0.5);
Packit 0986c0
	    PDF_lineto(myPDF, 1, 0.5);
Packit 0986c0
	    PDF_closepath_stroke(myPDF);
Packit 0986c0
	    if (number == 9) PDF_dot(0,0);
Packit 0986c0
	    break;
Packit 0986c0
	case 69+3:		/* TriangleDownWhitefilled */
Packit 0986c0
	    PDF_setgray_fill(myPDF, 1);
Packit 0986c0
	    /* FALLTHROUGH */
Packit 0986c0
	case 4+2*3:		/* TriangleDownFilled */
Packit 0986c0
	    PDF_moveto(myPDF, 0, -1.12);
Packit 0986c0
	    PDF_lineto(myPDF, -1, 0.5);
Packit 0986c0
	    PDF_lineto(myPDF, 1, 0.5);
Packit 0986c0
	    PDF_closepath_fill_stroke(myPDF);
Packit 0986c0
	    break;
Packit 0986c0
Packit 0986c0
	case 63+4:		/* DiamondEmpty */
Packit 0986c0
	case 3+2*4:		/* Diamond */
Packit 0986c0
	    PDF_moveto(myPDF, 0, -1);
Packit 0986c0
	    PDF_lineto(myPDF, 1, 0);
Packit 0986c0
	    PDF_lineto(myPDF, 0, 1);
Packit 0986c0
	    PDF_lineto(myPDF, -1, 0);
Packit 0986c0
	    PDF_closepath_stroke(myPDF);
Packit 0986c0
	    if (number == 11) PDF_dot(0,0);
Packit 0986c0
	    break;
Packit 0986c0
	case 69+4:		/* DiamondWhitefilled */
Packit 0986c0
	    PDF_setgray_fill(myPDF, 1);
Packit 0986c0
	    /* FALLTHROUGH */
Packit 0986c0
	case 4+2*4:		/* DiamondFilled */
Packit 0986c0
	    PDF_moveto(myPDF, 0, -1);
Packit 0986c0
	    PDF_lineto(myPDF, 1, 0);
Packit 0986c0
	    PDF_lineto(myPDF, 0, 1);
Packit 0986c0
	    PDF_lineto(myPDF, -1, 0);
Packit 0986c0
	    PDF_closepath_fill_stroke(myPDF);
Packit 0986c0
	    break;
Packit 0986c0
Packit 0986c0
	case 63+5:		/* PentagonEmpty */
Packit 0986c0
	case 3+2*5:		/* Pentagon */
Packit 0986c0
	    PDF_moveto(myPDF, 0, 1);
Packit 0986c0
	    PDF_lineto(myPDF, -0.95, 0.31);
Packit 0986c0
	    PDF_lineto(myPDF, -0.58, -0.81);
Packit 0986c0
	    PDF_lineto(myPDF, +0.58, -0.81);
Packit 0986c0
	    PDF_lineto(myPDF, +0.95, 0.31);
Packit 0986c0
	    PDF_closepath_stroke(myPDF);
Packit 0986c0
	    if (number == 13) PDF_dot(0,0);
Packit 0986c0
	    break;
Packit 0986c0
	case 69+5:		/* PentagonWhitefilled */
Packit 0986c0
	    PDF_setgray_fill(myPDF, 1);
Packit 0986c0
	    /* FALLTHROUGH */
Packit 0986c0
	case 4+2*5:		/* PentagonFilled */
Packit 0986c0
	    PDF_moveto(myPDF, 0, 1);
Packit 0986c0
	    PDF_lineto(myPDF, -0.95, 0.31);
Packit 0986c0
	    PDF_lineto(myPDF, -0.58, -0.81);
Packit 0986c0
	    PDF_lineto(myPDF, +0.58, -0.81);
Packit 0986c0
	    PDF_lineto(myPDF, +0.95, 0.31);
Packit 0986c0
	    PDF_closepath_fill_stroke(myPDF);
Packit 0986c0
	    break;
Packit 0986c0
Packit 0986c0
/* 15 + (0..15): circles with varying parts of'em filled. The added
Packit 0986c0
 * number is a bit-pattern of the 4 quadrants: 1 signals a quadrant
Packit 0986c0
 * filled */
Packit 0986c0
	case 15+0:
Packit 0986c0
	    PDF_moveto(myPDF, 0, 0);
Packit 0986c0
	    PDF_lineto(myPDF, 0, 1);
Packit 0986c0
	    PDF_arc(myPDF, 0, 0, 1, 90, 360+90);
Packit 0986c0
	    PDF_closepath_stroke(myPDF);
Packit 0986c0
	    break;
Packit 0986c0
Packit 0986c0
/* Generalize common code into a macro... */
Packit 0986c0
#define CIRCLE_SINGLE_PIESLICE(x, y, angle1, angle2)		\
Packit 0986c0
	    PDF_moveto(myPDF, 0, 0);				\
Packit 0986c0
	    PDF_lineto(myPDF, (x), (y));			\
Packit 0986c0
	    PDF_arc(myPDF, 0, 0, 1, (angle1), (angle2));	\
Packit 0986c0
	    PDF_lineto(myPDF, 0, 0);				\
Packit 0986c0
	    PDF_closepath(myPDF);				\
Packit 0986c0
	    PDF_fill_stroke(myPDF);				\
Packit 0986c0
	    PDF_arc(myPDF, 0, 0, 1, (angle2), (angle1) + 360);	\
Packit 0986c0
	    PDF_stroke(myPDF);					\
Packit 0986c0
	    break;
Packit 0986c0
Packit 0986c0
#define CIRCLE_SINGLE_QUADRANT(x, y, angle)			\
Packit 0986c0
	    CIRCLE_SINGLE_PIESLICE(x, y, angle, angle+90);
Packit 0986c0
	case 15+1:
Packit 0986c0
	    CIRCLE_SINGLE_QUADRANT(1, 0, 0);
Packit 0986c0
	case 15+2:
Packit 0986c0
	    CIRCLE_SINGLE_QUADRANT(0, 1, 90);
Packit 0986c0
	case 15+4:
Packit 0986c0
	    CIRCLE_SINGLE_QUADRANT(-1, 0, 180);
Packit 0986c0
	case 15+8:
Packit 0986c0
	    CIRCLE_SINGLE_QUADRANT(0, -1, 270);
Packit 0986c0
#undef CIRCLE_SINGLE_QUADRANT
Packit 0986c0
Packit 0986c0
#define CIRCLE_TWO_NEIGHBOR_QUADRANTS(x, y, angle)		\
Packit 0986c0
	    CIRCLE_SINGLE_PIESLICE(x, y, angle, angle+180)
Packit 0986c0
	case 15+3:
Packit 0986c0
	    CIRCLE_TWO_NEIGHBOR_QUADRANTS(1, 0, 0);
Packit 0986c0
	case 15+6:
Packit 0986c0
	    CIRCLE_TWO_NEIGHBOR_QUADRANTS(0, 1, 90);
Packit 0986c0
	case 15+12:
Packit 0986c0
	    CIRCLE_TWO_NEIGHBOR_QUADRANTS(-1, 0, 180);
Packit 0986c0
	case 15+9:
Packit 0986c0
	    CIRCLE_TWO_NEIGHBOR_QUADRANTS(0, -1, 270);
Packit 0986c0
#undef CIRCLE_TWO_NEIGHBOR_QUADRANTS
Packit 0986c0
Packit 0986c0
#define CIRCLE_TWO_OPPOSING_QUADRANTS(x, y, angle)		\
Packit 0986c0
	    PDF_moveto(myPDF, 0, 0);				\
Packit 0986c0
	    PDF_lineto(myPDF, x, y);				\
Packit 0986c0
	    PDF_arc(myPDF, 0, 0, 1, angle, angle + 90);		\
Packit 0986c0
	    PDF_lineto(myPDF, 0, 0);				\
Packit 0986c0
	    PDF_fill_stroke(myPDF);				\
Packit 0986c0
	    PDF_moveto(myPDF, 0, 0);				\
Packit 0986c0
	    PDF_lineto(myPDF, -x, -y);				\
Packit 0986c0
	    PDF_arc(myPDF, 0, 0, 1, angle + 180, angle + 270);	\
Packit 0986c0
	    PDF_lineto(myPDF, 0, 0);				\
Packit 0986c0
	    PDF_fill_stroke(myPDF);				\
Packit 0986c0
	    PDF_arc(myPDF, 0, 0, 1, angle + 90, angle + 360);	\
Packit 0986c0
	    PDF_stroke(myPDF);					\
Packit 0986c0
	    break;
Packit 0986c0
	case 15+5:
Packit 0986c0
	    CIRCLE_TWO_OPPOSING_QUADRANTS(1, 0, 0);
Packit 0986c0
	case 15+10:
Packit 0986c0
	    CIRCLE_TWO_OPPOSING_QUADRANTS(0, 1, 90);
Packit 0986c0
#undef CIRCLE_TWO_OPPOSING_QUADRANTS
Packit 0986c0
Packit 0986c0
#define CIRCLE_THREE_QUADRANTS(x, y, angle)			\
Packit 0986c0
	    CIRCLE_SINGLE_PIESLICE(x, y, angle, angle+270)
Packit 0986c0
	case 15+7:
Packit 0986c0
	    CIRCLE_THREE_QUADRANTS(1, 0, 0);
Packit 0986c0
	case 15+14:
Packit 0986c0
	    CIRCLE_THREE_QUADRANTS(0, 1, 90);
Packit 0986c0
	case 15+13:
Packit 0986c0
	    CIRCLE_THREE_QUADRANTS(-1, 0, 180);
Packit 0986c0
	case 15+11:
Packit 0986c0
	    CIRCLE_THREE_QUADRANTS(0, -1, 270);
Packit 0986c0
#undef CIRCLE_THREE_QUADRANTS
Packit 0986c0
#undef CIRCLE_SINGLE_PIESLICE
Packit 0986c0
Packit 0986c0
	case 15+15:
Packit 0986c0
	    PDF_circle(myPDF, 0, 0, 1);
Packit 0986c0
	    PDF_closepath_fill_stroke(myPDF);
Packit 0986c0
	    break;
Packit 0986c0
Packit 0986c0
Packit 0986c0
/*************************************************************************/
Packit 0986c0
/* 31 + (0..15): squares with different quadrants of them filled in. */
Packit 0986c0
/*************************************************************************/
Packit 0986c0
/*************************************************************************/
Packit 0986c0
/* 47 + (0..15): diamonds with filled quadrants as given by bit pattern  */
Packit 0986c0
/*   Diamonds are drawn as squares rotated by 45 degrees, so can use
Packit 0986c0
 * fall-through from diamond to squares, and re-use some macros. */
Packit 0986c0
/*************************************************************************/
Packit 0986c0
	case 47+0:
Packit 0986c0
	    PDF_rotate(myPDF, 45);
Packit 0986c0
	    /* FALLTHROUGH */
Packit 0986c0
	case 31+0:
Packit 0986c0
	    PDF_moveto(myPDF, 0, 0);
Packit 0986c0
	    PDF_lineto(myPDF, 0, 1);
Packit 0986c0
	    PDF_lineto(myPDF, -1, 1);
Packit 0986c0
	    PDF_lineto(myPDF, -1, -1);
Packit 0986c0
	    PDF_lineto(myPDF, 1, -1);
Packit 0986c0
	    PDF_lineto(myPDF, 1, 1);
Packit 0986c0
	    PDF_lineto(myPDF, 0, 1);
Packit 0986c0
	    PDF_stroke(myPDF);
Packit 0986c0
	    break;
Packit 0986c0
Packit 0986c0
	case 47+15:
Packit 0986c0
	    PDF_rotate(myPDF, 45);
Packit 0986c0
	    /* FALLTHROUGH */
Packit 0986c0
	case 31+15:
Packit 0986c0
	    PDF_moveto(myPDF, -1, 1);
Packit 0986c0
	    PDF_lineto(myPDF, -1, -1);
Packit 0986c0
	    PDF_lineto(myPDF, 1, -1);
Packit 0986c0
	    PDF_lineto(myPDF, 1, 1);
Packit 0986c0
	    PDF_closepath_fill_stroke(myPDF);
Packit 0986c0
	    break;
Packit 0986c0
Packit 0986c0
/* macros defining shapes of the partly filled symbols. Done by
Packit 0986c0
 * rotating the starting point (x0, y0) by 90 degrees or 45 degrees
Packit 0986c0
 * (with length adjustment).  The rotations can be done without
Packit 0986c0
 * trigonometric function calls, since their values are known:
Packit 0986c0
 * cos(90)=0, sin(90)=1, cos(45)=sin(45)=1/sqrt(2).  A good compiler
Packit 0986c0
 * should be able to optimize away all the local variables and
Packit 0986c0
 * loops...  */
Packit 0986c0
Packit 0986c0
#define SQUARE_SINGLE_PIESLICE(x0, y0, quadrants)			\
Packit 0986c0
	    {								\
Packit 0986c0
		int quadrant = 0;					\
Packit 0986c0
		int x= x0, y=y0;					\
Packit 0986c0
		PDF_moveto(myPDF, 0, 0);				\
Packit 0986c0
		PDF_lineto(myPDF, x, y);				\
Packit 0986c0
		/* poor man's rotation by 45 and 90 degrees around the	\
Packit 0986c0
		 * square's outline. */					\
Packit 0986c0
		while (quadrant++ < quadrants) {			\
Packit 0986c0
		    int dummy;						\
Packit 0986c0
		    PDF_lineto(myPDF, x-y, x+y);			\
Packit 0986c0
		    dummy = x; x = -y; y = dummy;			\
Packit 0986c0
		}							\
Packit 0986c0
		PDF_lineto(myPDF, x, y);				\
Packit 0986c0
		PDF_closepath_fill_stroke(myPDF);			\
Packit 0986c0
		PDF_moveto(myPDF, x, y);				\
Packit 0986c0
		while (quadrant++ <= 4) {				\
Packit 0986c0
		    int dummy;						\
Packit 0986c0
		    PDF_lineto(myPDF, x-y, x+y);			\
Packit 0986c0
		    dummy = x; x = -y; y = dummy;			\
Packit 0986c0
		}							\
Packit 0986c0
		PDF_lineto(myPDF, x, y);				\
Packit 0986c0
		PDF_stroke(myPDF);					\
Packit 0986c0
	    }								\
Packit 0986c0
	    break;
Packit 0986c0
Packit 0986c0
#define SQUARE_TWO_OPPOSING_QUADRANTS(x0, y0, angle)	\
Packit 0986c0
	    {						\
Packit 0986c0
		int x = x0, y = y0, dummy;		\
Packit 0986c0
		int counter = 0;			\
Packit 0986c0
							\
Packit 0986c0
		while (counter++ < 2) {			\
Packit 0986c0
		    PDF_moveto(myPDF, 0, 0);		\
Packit 0986c0
		    PDF_lineto(myPDF, x, y);		\
Packit 0986c0
		    PDF_lineto(myPDF, x-y, x+y);	\
Packit 0986c0
		    dummy = x; x = -y; y = dummy;	\
Packit 0986c0
		    PDF_lineto(myPDF, x, y);		\
Packit 0986c0
		    PDF_closepath_fill_stroke(myPDF);	\
Packit 0986c0
							\
Packit 0986c0
		    PDF_moveto(myPDF, x, y);		\
Packit 0986c0
		    PDF_lineto(myPDF, x-y, x+y);	\
Packit 0986c0
		    dummy = x; x = -y; y = dummy;	\
Packit 0986c0
		    PDF_lineto(myPDF, x, y);		\
Packit 0986c0
		    PDF_stroke(myPDF);			\
Packit 0986c0
		}					\
Packit 0986c0
		break;					\
Packit 0986c0
	    }
Packit 0986c0
Packit 0986c0
/* Macros for diamonds just prepend the rotation and then call those
Packit 0986c0
 * for squares: */
Packit 0986c0
#define DIAMOND_SINGLE_PIESLICE(x, y, quadrants)	\
Packit 0986c0
	    PDF_rotate(myPDF, 45);			\
Packit 0986c0
	    SQUARE_SINGLE_PIESLICE(x, y, quadrants);
Packit 0986c0
#define DIAMOND_TWO_OPPOSING_QUADRANTS(x, y, angle)	\
Packit 0986c0
	    PDF_rotate(myPDF, 45);			\
Packit 0986c0
	    SQUARE_TWO_OPPOSING_QUADRANTS(x, y, angle);
Packit 0986c0
Packit 0986c0
/* ... and now all the individual cases. The 'angle' arguments' are
Packit 0986c0
 * purely for the sake of easing cut'n'paste with the circle case */
Packit 0986c0
#define SQUARE_SINGLE_QUADRANT(x, y, angle)			\
Packit 0986c0
	    SQUARE_SINGLE_PIESLICE(x, y, 1);
Packit 0986c0
	case 31+1:
Packit 0986c0
	    SQUARE_SINGLE_QUADRANT(1, 0, 0);
Packit 0986c0
	case 31+2:
Packit 0986c0
	    SQUARE_SINGLE_QUADRANT(0, 1, 90);
Packit 0986c0
	case 31+4:
Packit 0986c0
	    SQUARE_SINGLE_QUADRANT(-1, 0, 180);
Packit 0986c0
	case 31+8:
Packit 0986c0
	    SQUARE_SINGLE_QUADRANT(0, -1, 270);
Packit 0986c0
#undef SQUARE_SINGLE_QUADRANT
Packit 0986c0
Packit 0986c0
#define SQUARE_TWO_NEIGHBOR_QUADRANTS(x, y, angle)		\
Packit 0986c0
	    SQUARE_SINGLE_PIESLICE(x, y, 2)
Packit 0986c0
	case 31+3:
Packit 0986c0
	    SQUARE_TWO_NEIGHBOR_QUADRANTS(1, 0, 0);
Packit 0986c0
	case 31+6:
Packit 0986c0
	    SQUARE_TWO_NEIGHBOR_QUADRANTS(0, 1, 90);
Packit 0986c0
	case 31+12:
Packit 0986c0
	    SQUARE_TWO_NEIGHBOR_QUADRANTS(-1, 0, 180);
Packit 0986c0
	case 31+9:
Packit 0986c0
	    SQUARE_TWO_NEIGHBOR_QUADRANTS(0, -1, 270);
Packit 0986c0
#undef SQUARE_TWO_NEIGHBOR_QUADRANTS
Packit 0986c0
Packit 0986c0
	case 31+5:
Packit 0986c0
	    SQUARE_TWO_OPPOSING_QUADRANTS(1, 0, 0);
Packit 0986c0
	case 31+10:
Packit 0986c0
	    SQUARE_TWO_OPPOSING_QUADRANTS(0, 1, 90);
Packit 0986c0
Packit 0986c0
#define SQUARE_THREE_QUADRANTS(x, y, angle)			\
Packit 0986c0
	    SQUARE_SINGLE_PIESLICE(x, y, 3)
Packit 0986c0
	case 31+7:
Packit 0986c0
	    SQUARE_THREE_QUADRANTS(1, 0, 0);
Packit 0986c0
	case 31+14:
Packit 0986c0
	    SQUARE_THREE_QUADRANTS(0, 1, 90);
Packit 0986c0
	case 31+13:
Packit 0986c0
	    SQUARE_THREE_QUADRANTS(-1, 0, 180);
Packit 0986c0
	case 31+11:
Packit 0986c0
	    SQUARE_THREE_QUADRANTS(0, -1, 270);
Packit 0986c0
#undef SQUARE_THREE_QUADRANTS
Packit 0986c0
Packit 0986c0
#define DIAMOND_SINGLE_QUADRANT(x, y, angle)			\
Packit 0986c0
	    DIAMOND_SINGLE_PIESLICE(x, y, 1)
Packit 0986c0
	case 47+1:
Packit 0986c0
	    DIAMOND_SINGLE_QUADRANT(1, 0, 0);
Packit 0986c0
	case 47+2:
Packit 0986c0
	    DIAMOND_SINGLE_QUADRANT(0, 1, 90);
Packit 0986c0
	case 47+4:
Packit 0986c0
	    DIAMOND_SINGLE_QUADRANT(-1, 0, 180);
Packit 0986c0
	case 47+8:
Packit 0986c0
	    DIAMOND_SINGLE_QUADRANT(0, -1, 270);
Packit 0986c0
#undef DIAMOND_SINGLE_QUADRANT
Packit 0986c0
Packit 0986c0
#define DIAMOND_TWO_NEIGHBOR_QUADRANTS(x, y, angle)		\
Packit 0986c0
	    DIAMOND_SINGLE_PIESLICE(x, y, 2)
Packit 0986c0
	case 47+3:
Packit 0986c0
	    DIAMOND_TWO_NEIGHBOR_QUADRANTS(1, 0, 0);
Packit 0986c0
	case 47+6:
Packit 0986c0
	    DIAMOND_TWO_NEIGHBOR_QUADRANTS(0, 1, 90);
Packit 0986c0
	case 47+12:
Packit 0986c0
	    DIAMOND_TWO_NEIGHBOR_QUADRANTS(-1, 0, 180);
Packit 0986c0
	case 47+9:
Packit 0986c0
	    DIAMOND_TWO_NEIGHBOR_QUADRANTS(0, -1, 270);
Packit 0986c0
#undef DIAMOND_TWO_NEIGHBOR_QUADRANTS
Packit 0986c0
Packit 0986c0
Packit 0986c0
	case 47+5:
Packit 0986c0
	    DIAMOND_TWO_OPPOSING_QUADRANTS(1, 0, 0);
Packit 0986c0
	case 47+10:
Packit 0986c0
	    DIAMOND_TWO_OPPOSING_QUADRANTS(0, 1, 90);
Packit 0986c0
#undef DIAMOND_TWO_OPPOSING_QUADRANTS
Packit 0986c0
#undef SQUARE_TWO_OPPOSING_QUADRANTS
Packit 0986c0
Packit 0986c0
#define DIAMOND_THREE_QUADRANTS(x, y, angle)			\
Packit 0986c0
	    DIAMOND_SINGLE_PIESLICE(x, y, 3)
Packit 0986c0
	case 47+7:
Packit 0986c0
	    DIAMOND_THREE_QUADRANTS(1, 0, 0);
Packit 0986c0
	case 47+14:
Packit 0986c0
	    DIAMOND_THREE_QUADRANTS(0, 1, 90);
Packit 0986c0
	case 47+13:
Packit 0986c0
	    DIAMOND_THREE_QUADRANTS(-1, 0, 180);
Packit 0986c0
	case 47+11:
Packit 0986c0
	    DIAMOND_THREE_QUADRANTS(0, -1, 270);
Packit 0986c0
#undef DIAMOND_THREE_QUADRANTS
Packit 0986c0
#undef DIAMOND_SINGLE_PIESLICE
Packit 0986c0
#undef SQUARE_SINGLE_PIESLICE
Packit 0986c0
Packit 0986c0
	default:
Packit 0986c0
	    int_warn(NO_CARET, "PDF: unknown point type number %d", number);
Packit 0986c0
	}
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    PDF_restore(myPDF);
Packit 0986c0
    PDF_xLast = x;
Packit 0986c0
    PDF_yLast = y;
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
Packit 0986c0
TERM_PUBLIC int
Packit 0986c0
PDF_justify_text (enum JUSTIFY mode)
Packit 0986c0
{
Packit 0986c0
    PDF_TextJust = mode;
Packit 0986c0
    return (TRUE);
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
Packit 0986c0
TERM_PUBLIC int
Packit 0986c0
PDF_text_angle (int ang)
Packit 0986c0
{
Packit 0986c0
    PDF_TextAngle = ang;
Packit 0986c0
    return (TRUE);
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
PDF_put_text (unsigned int x, unsigned int y, const char *str)
Packit 0986c0
{
Packit 0986c0
    char *alignment = NULL;
Packit 0986c0
    double h = x, v = y;
Packit 0986c0
Packit 0986c0
    PDF_PathClose ();
Packit 0986c0
Packit 0986c0
    /* horizontal justification*/
Packit 0986c0
    switch (PDF_TextJust) {
Packit 0986c0
    case LEFT:
Packit 0986c0
	alignment = "left";
Packit 0986c0
	break;
Packit 0986c0
    case CENTRE:
Packit 0986c0
	alignment = "center";
Packit 0986c0
	break;
Packit 0986c0
    case RIGHT:
Packit 0986c0
	alignment = "right";
Packit 0986c0
	break;
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    if (PDF_TextAngle) {
Packit 0986c0
	PDF_save(myPDF);
Packit 0986c0
	PDF_translate(myPDF, h, v);
Packit 0986c0
	PDF_rotate(myPDF, PDF_TextAngle);
Packit 0986c0
	/* vertical justification*/
Packit 0986c0
	PDF_translate(myPDF, 0, -(PDF_fontAscent-PDF_fontDescent)/2);
Packit 0986c0
	PDF_show_boxed(myPDF, str, 0,0, 0, 0, alignment, NULL);
Packit 0986c0
	PDF_restore(myPDF);
Packit 0986c0
    } else {
Packit 0986c0
	/* vertical justification*/
Packit 0986c0
	v -= (PDF_fontAscent - PDF_fontDescent) / 2;
Packit 0986c0
	PDF_show_boxed(myPDF, str, h , v, 0, 0, alignment, NULL);
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
Packit 0986c0
TERM_PUBLIC int
Packit 0986c0
PDF_set_font (const char *font)
Packit 0986c0
{
Packit 0986c0
    /* FIXME: This condition is somehow triggered by enhanced_recursion */
Packit 0986c0
    if (font == PDF_fontNameCur)
Packit 0986c0
	;
Packit 0986c0
Packit 0986c0
    else if (!font || !(*font)) {
Packit 0986c0
	strcpy (PDF_fontNameCur, PDF_fontNameDef);
Packit 0986c0
	PDF_fontSizeCur = PDF_fontSizeDef;
Packit 0986c0
    } else {
Packit 0986c0
	int sep = strcspn(font,",");
Packit 0986c0
	if (sep > 0) {
Packit 0986c0
	    strncpy(PDF_fontNameCur,font,sep);
Packit 0986c0
	    PDF_fontNameCur[sep] = NUL;
Packit 0986c0
	}
Packit 0986c0
	if (font[sep] == ',')
Packit 0986c0
	    sscanf(&(font[sep+1]), "%lf", &PDF_fontSizeCur);
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    PDF_PathClose();
Packit 0986c0
    PDF_SetFont();
Packit 0986c0
Packit 0986c0
    term->h_char = PDF_fontAvWidth;
Packit 0986c0
    term->v_char = (PDF_fontAscent + PDF_fontDescent + PDF_fontLeading);
Packit 0986c0
Packit 0986c0
    return (TRUE);
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
PDF_boxfill(int style, unsigned int x1, unsigned int y1,
Packit 0986c0
	    unsigned int width, unsigned int height)
Packit 0986c0
{
Packit 0986c0
    gpiPoint corner[4];
Packit 0986c0
Packit 0986c0
	corner[0].x = x1;        corner[0].y = y1;
Packit 0986c0
	corner[1].x = x1+width;  corner[1].y = y1;
Packit 0986c0
	corner[2].x = x1+width;  corner[2].y = y1+height;
Packit 0986c0
	corner[3].x = x1;        corner[3].y = y1+height;
Packit 0986c0
Packit 0986c0
	corner->style = style;
Packit 0986c0
	PDF_filled_polygon(4, corner);
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
PDF_filled_polygon(int points, gpiPoint* corners)
Packit 0986c0
{
Packit 0986c0
    int i;
Packit 0986c0
    int fillpar = corners->style >> 4;
Packit 0986c0
    int style = corners->style &= 0xf;
Packit 0986c0
Packit 0986c0
    PDF_PathClose();
Packit 0986c0
    PDF_save(myPDF);
Packit 0986c0
Packit 0986c0
    switch (style) {
Packit 0986c0
	case FS_EMPTY: /* fill with white */
Packit 0986c0
	    PDF_setgray(myPDF, 1);
Packit 0986c0
	    break;
Packit 0986c0
	case FS_TRANSPARENT_SOLID:
Packit 0986c0
#if !HAVE_OLD_LIBPDF
Packit 0986c0
	    {
Packit 0986c0
		/* FIXME: This attribute will be in effect until the end of   */
Packit 0986c0
		/* the current page. We should explicitly reset it to restore */
Packit 0986c0
		/* opaque fill areas as the default. But when should it be?   */
Packit 0986c0
		char density[18];
Packit 0986c0
		double red   = PDF_current_rgb.r;
Packit 0986c0
		double green = PDF_current_rgb.g;
Packit 0986c0
		double blue  = PDF_current_rgb.b;
Packit 0986c0
		sprintf(density,"opacityfill=%4.2f", (double)fillpar*0.01);
Packit 0986c0
		i = PDF_create_gstate(myPDF, density);
Packit 0986c0
		PDF_set_gstate(myPDF, i);
Packit 0986c0
		if (PDF_monochrome)
Packit 0986c0
		    PDF_setgray_fill(myPDF, PDF_current_gray);
Packit 0986c0
		else
Packit 0986c0
		    PDF_setrgbcolor_fill(myPDF, red, green, blue);
Packit 0986c0
		break;
Packit 0986c0
	    }
Packit 0986c0
#endif
Packit 0986c0
	case FS_SOLID:
Packit 0986c0
	    {
Packit 0986c0
		double fact = (double)fillpar * 0.01;
Packit 0986c0
		double _fact = (double)(100-fillpar) * 0.01;
Packit 0986c0
		double red   = PDF_current_rgb.r * fact + _fact;
Packit 0986c0
		double green = PDF_current_rgb.g * fact + _fact;
Packit 0986c0
		double blue  = PDF_current_rgb.b * fact + _fact;
Packit 0986c0
		if (PDF_monochrome)
Packit 0986c0
		    PDF_setgray_fill(myPDF, PDF_current_gray);
Packit 0986c0
		else
Packit 0986c0
		    PDF_setrgbcolor_fill(myPDF, red, green, blue);
Packit 0986c0
	    }
Packit 0986c0
	    break;
Packit 0986c0
Packit 0986c0
#if !HAVE_OLD_LIBPDF
Packit 0986c0
	case FS_PATTERN:
Packit 0986c0
	    fillpar = fillpar % (PDF_patterns + 1) /* 0 == white */;
Packit 0986c0
	    /* Fill in solid background before drawing pattern */
Packit 0986c0
	    /* NOTE:  kpdf/xpdf would accept this as part of the pattern definition */
Packit 0986c0
	    /*        but acroread does not. So for compatibility we do the fill in */
Packit 0986c0
	    /*        a separate step, despite its inefficiency.                    */
Packit 0986c0
	    if (fillpar != 0) {
Packit 0986c0
		PDF_setcolor(myPDF, "fill", "rgb", 1, 1, 1, 0 /* unused */);
Packit 0986c0
		PDF_moveto(myPDF, corners[0].x, corners[0].y);
Packit 0986c0
		for (i=1; i
Packit 0986c0
		    PDF_lineto(myPDF, corners[i].x, corners[i].y);
Packit 0986c0
		PDF_lineto(myPDF, corners[0].x, corners[0].y);
Packit 0986c0
		PDF_fill(myPDF);
Packit 0986c0
		PDF_restore(myPDF);
Packit 0986c0
		PDF_save(myPDF);
Packit 0986c0
	    }
Packit 0986c0
	    /* NOTE: Fall through to the actual pattern code */
Packit 0986c0
	case FS_TRANSPARENT_PATTERN:
Packit 0986c0
	    fillpar = fillpar % (PDF_patterns + 1) /* 0 == white */;
Packit 0986c0
	    switch (fillpar) {
Packit 0986c0
		case 0:
Packit 0986c0
		    /* fill with white */
Packit 0986c0
		    PDF_setcolor(myPDF, "fill", "rgb", 1, 1, 1, 0 /* unused */);
Packit 0986c0
		    break;
Packit 0986c0
		default:
Packit 0986c0
		    PDF_setcolor(myPDF, "fill", "pattern", PDF_patternHandles[fillpar - 1], 0, 0, 0);
Packit 0986c0
	    }
Packit 0986c0
	    break;
Packit 0986c0
#endif
Packit 0986c0
Packit 0986c0
	default:
Packit 0986c0
	    break;
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    PDF_moveto(myPDF, corners[0].x, corners[0].y);
Packit 0986c0
    for (i=1; i
Packit 0986c0
	PDF_lineto(myPDF, corners[i].x, corners[i].y);
Packit 0986c0
    PDF_lineto(myPDF, corners[0].x, corners[0].y);
Packit 0986c0
    PDF_fill(myPDF);
Packit 0986c0
    PDF_restore(myPDF);
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
TERM_PUBLIC int
Packit 0986c0
PDF_make_palette(t_sm_palette *palette)
Packit 0986c0
{
Packit 0986c0
    if (palette == NULL) {
Packit 0986c0
	/* pdf can do continuous colors */
Packit 0986c0
	return 0;
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    return 0;
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
PDF_set_color(t_colorspec *colorspec)
Packit 0986c0
{
Packit 0986c0
    if (colorspec->type == TC_LT) {
Packit 0986c0
	unsigned int irgb = pm3d_color_names_tbl[ 1 + PDF_Pen_RealID(colorspec->lt) ].value;
Packit 0986c0
	PDF_current_rgb.r = (double)((irgb >> 16) & 0xff) / 255.;
Packit 0986c0
	PDF_current_rgb.g = (double)((irgb >>  8) & 0xff) / 255.;
Packit 0986c0
	PDF_current_rgb.b = (double)((irgb      ) & 0xff) / 255.;
Packit 0986c0
	PDF_current_gray = 0.0; /* monochrome mode only */
Packit 0986c0
    } else if (colorspec->type == TC_FRAC) {
Packit 0986c0
	rgb1maxcolors_from_gray( colorspec->value, &PDF_current_rgb);
Packit 0986c0
	PDF_current_gray = colorspec->value; /* monochrome mode only */
Packit 0986c0
    } else if (colorspec->type == TC_RGB) {
Packit 0986c0
	PDF_current_rgb.r = (double)((colorspec->lt >> 16 ) & 255) / 255.;
Packit 0986c0
	PDF_current_rgb.g = (double)((colorspec->lt >> 8 ) & 255) / 255.;
Packit 0986c0
	PDF_current_rgb.b = (double)(colorspec->lt & 255) / 255.;
Packit 0986c0
    } else
Packit 0986c0
	return;
Packit 0986c0
Packit 0986c0
    /* make sure that the path is stroked with the current color
Packit 0986c0
     * before changing the color */
Packit 0986c0
    PDF_PathClose();
Packit 0986c0
Packit 0986c0
    if (PDF_monochrome && colorspec->type != TC_RGB)
Packit 0986c0
	PDF_setgray(myPDF, PDF_current_gray);  /* FIXME - Should this be NTSC(current_rgb)? */
Packit 0986c0
    else
Packit 0986c0
	PDF_setrgbcolor(myPDF, PDF_current_rgb.r, PDF_current_rgb.g, PDF_current_rgb.b);
Packit 0986c0
Packit 0986c0
    /* mark linetype invalid so that the color will be
Packit 0986c0
     * set when PDF_linetype() is called next */
Packit 0986c0
    PDF_LineType = LT_UNDEFINED;
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
PDF_previous_palette()
Packit 0986c0
{
Packit 0986c0
}
Packit 0986c0
 
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
PDF_image (unsigned int M, unsigned int N, coordval * image, gpiPoint * corner, t_imagecolor color_mode)
Packit 0986c0
{
Packit 0986c0
    unsigned char *pixel;
Packit 0986c0
    float xscale, yscale;
Packit 0986c0
    int i, im;
Packit 0986c0
Packit 0986c0
    /* Allocate memory to hold a copy of the entire image in raw RGB format */
Packit 0986c0
    unsigned char *rawrgb = gp_alloc( M*N*3, "Raw RGB image");
Packit 0986c0
Packit 0986c0
    /* Convert the input image into raw RGB 24-bit color representation */
Packit 0986c0
    if (color_mode == IC_RGB) {
Packit 0986c0
	for (i=0, pixel=rawrgb; i
Packit 0986c0
	    rgb_color rgb1;
Packit 0986c0
	    rgb255_color rgb255;
Packit 0986c0
	    rgb1.r = image[i++];
Packit 0986c0
	    rgb1.g = image[i++];
Packit 0986c0
	    rgb1.b = image[i++];
Packit 0986c0
	    rgb255_from_rgb1( rgb1, &rgb255 );
Packit 0986c0
	    *pixel++ = rgb255.r;
Packit 0986c0
	    *pixel++ = rgb255.g;
Packit 0986c0
	    *pixel++ = rgb255.b;
Packit 0986c0
	}
Packit 0986c0
    } else {
Packit 0986c0
        for (i=0, pixel=rawrgb; i< N*M; i++) {
Packit 0986c0
	    if (isnan(image[i])) {
Packit 0986c0
		/* Transparent would be better! */
Packit 0986c0
		*pixel++ = 255;
Packit 0986c0
		*pixel++ = 255;
Packit 0986c0
		*pixel++ = 255;
Packit 0986c0
	    } else {
Packit 0986c0
		rgb255_color rgb;
Packit 0986c0
		rgb255maxcolors_from_gray(image[i], &rgb);
Packit 0986c0
		*pixel++ = rgb.r;
Packit 0986c0
		*pixel++ = rgb.g;
Packit 0986c0
		*pixel++ = rgb.b;
Packit 0986c0
	    }
Packit 0986c0
	}
Packit 0986c0
    }
Packit 0986c0
      
Packit 0986c0
    /* Describe this image to PDF library */
Packit 0986c0
    im = PDF_open_image( myPDF, "raw", "memory", (char *)rawrgb,
Packit 0986c0
			 (long)(M*N*3), (int)M, (int)N,
Packit 0986c0
			 3, 8,				/* 3 colors, 8 bits each */
Packit 0986c0
			 "");
Packit 0986c0
Packit 0986c0
    /* Clip to bounding box requested */
Packit 0986c0
	PDF_save(myPDF);
Packit 0986c0
	PDF_moveto(myPDF, corner[2].x, corner[2].y);
Packit 0986c0
	PDF_lineto(myPDF, corner[2].x, corner[3].y);
Packit 0986c0
	PDF_lineto(myPDF, corner[3].x, corner[3].y);
Packit 0986c0
	PDF_lineto(myPDF, corner[3].x, corner[2].y);
Packit 0986c0
	PDF_closepath(myPDF);
Packit 0986c0
	PDF_clip(myPDF);
Packit 0986c0
Packit 0986c0
/* Scale and copy into the main PDF image */
Packit 0986c0
	xscale = fabs((float)corner[1].x - (float)corner[0].x) / (float)M;
Packit 0986c0
	yscale = fabs((float)corner[1].y - (float)corner[0].y) / (float)N;
Packit 0986c0
	PDF_translate(myPDF, corner[0].x, corner[0].y);
Packit 0986c0
	PDF_scale(myPDF, xscale, yscale);
Packit 0986c0
	PDF_translate(myPDF, 0, -(float)N);
Packit 0986c0
	PDF_place_image(myPDF, im, 0.0, 0.0, 1.0 );
Packit 0986c0
	PDF_restore(myPDF);
Packit 0986c0
Packit 0986c0
    /* Clean up */
Packit 0986c0
	PDF_close_image(myPDF, im);
Packit 0986c0
	free(rawrgb);
Packit 0986c0
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
/*
Packit 0986c0
 * Ethan A Merritt November 2003
Packit 0986c0
 *	- support for enhanced text mode
Packit 0986c0
 * BUGS:
Packit 0986c0
 *	- The baseline is not consistent if font size changes within a string.
Packit 0986c0
 *	- Placement of overprinted characters is not correct.
Packit 0986c0
 *	- libpdf exits if the requested font is not recognized.
Packit 0986c0
 *	- I implement text-rotation by hand, but it may be possible to use
Packit 0986c0
 *	  a gsave/translate/rotate/.../grestore sequence instead.
Packit 0986c0
 */
Packit 0986c0
Packit 0986c0
static TBOOLEAN ENHpdf_opened_string;
Packit 0986c0
Packit 0986c0
/* used in determining height of processed text */
Packit 0986c0
static float ENHpdf_base;
Packit 0986c0
Packit 0986c0
/* use these so that we don't over-write the current font settings in pdf_state */
Packit 0986c0
static double  ENHpdf_fontsize;
Packit 0986c0
static char   *ENHpdf_font;
Packit 0986c0
Packit 0986c0
/* A global flag that tells us this run is just to determine text size */
Packit 0986c0
static TBOOLEAN ENHpdf_sizeonly = FALSE;
Packit 0986c0
Packit 0986c0
static TBOOLEAN ENHpdf_show = TRUE;
Packit 0986c0
static int ENHpdf_overprint = 0;
Packit 0986c0
static TBOOLEAN ENHpdf_widthflag = FALSE;
Packit 0986c0
static unsigned int ENHpdf_xsave, ENHpdf_ysave;
Packit 0986c0
Packit 0986c0
/* Start a new string fragment */
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
ENHPDF_OPEN(
Packit 0986c0
    char *fontname,
Packit 0986c0
    double fontsize, double base,
Packit 0986c0
    TBOOLEAN widthflag, TBOOLEAN showflag,
Packit 0986c0
    int overprint)
Packit 0986c0
{
Packit 0986c0
    /* If the overprint code requests a save or request, that's all we do */
Packit 0986c0
    if (overprint == 3) {
Packit 0986c0
	ENHpdf_xsave = PDF_xLast;
Packit 0986c0
	ENHpdf_ysave = PDF_yLast;
Packit 0986c0
	return;
Packit 0986c0
    } else if (overprint == 4) {
Packit 0986c0
	PDF_move(ENHpdf_xsave, ENHpdf_ysave);
Packit 0986c0
	return;
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    if (!ENHpdf_opened_string) {
Packit 0986c0
	ENHpdf_opened_string = TRUE;
Packit 0986c0
	enhanced_cur_text = &enhanced_text[0];
Packit 0986c0
	ENHpdf_font = fontname;
Packit 0986c0
	ENHpdf_fontsize = fontsize;
Packit 0986c0
	ENHpdf_base = base * PDF_RESOLUTION;
Packit 0986c0
	ENHpdf_show = showflag;
Packit 0986c0
	ENHpdf_overprint = overprint;
Packit 0986c0
	ENHpdf_widthflag = widthflag;
Packit 0986c0
    }
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
/* Write a string fragment and update the current position */
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
ENHPDF_FLUSH()
Packit 0986c0
{
Packit 0986c0
    int x, y;
Packit 0986c0
    float stringlength;
Packit 0986c0
Packit 0986c0
	if (ENHpdf_opened_string) {
Packit 0986c0
	    ENHpdf_opened_string = FALSE;
Packit 0986c0
	    *enhanced_cur_text = '\0';
Packit 0986c0
	    x = PDF_xLast;
Packit 0986c0
	    y = PDF_yLast;
Packit 0986c0
	    x -= sin((double)PDF_TextAngle * M_PI_2/90.) * ENHpdf_base;
Packit 0986c0
	    y += cos((double)PDF_TextAngle * M_PI_2/90.) * ENHpdf_base;
Packit 0986c0
	    x += sin((double)PDF_TextAngle * M_PI_2/90.) * (double)PDF_fontAvWidth/2.;
Packit 0986c0
	    y -= cos((double)PDF_TextAngle * M_PI_2/90.) * (double)PDF_fontAvWidth/2.;
Packit 0986c0
Packit 0986c0
	    /* Select current font for enhanced text fragment, then restore context */
Packit 0986c0
	    if (1) {
Packit 0986c0
		char save_fontname[MAX_ID_LEN + 1];
Packit 0986c0
		double save_fontsize = PDF_fontSizeCur;
Packit 0986c0
		    strcpy(save_fontname,PDF_fontNameCur);
Packit 0986c0
		    PDF_fontSizeCur = ENHpdf_fontsize / PDF_fontscale;
Packit 0986c0
		    PDF_set_font(ENHpdf_font);
Packit 0986c0
		    strcpy(PDF_fontNameCur,save_fontname);
Packit 0986c0
		    PDF_fontSizeCur = save_fontsize;
Packit 0986c0
	    }
Packit 0986c0
Packit 0986c0
	    /* Find length of string in current font */
Packit 0986c0
	    stringlength = PDF_stringwidth(myPDF, enhanced_text,
Packit 0986c0
		PDF_currentFontHandle, ENHpdf_fontsize);
Packit 0986c0
	    stringlength *= PDF_RESOLUTION;
Packit 0986c0
Packit 0986c0
	    if (ENHpdf_show && !ENHpdf_sizeonly) {
Packit 0986c0
		if (PDF_TextAngle == 0 ) {
Packit 0986c0
		    /* PDF_show(myPDF, enhanced_text); */
Packit 0986c0
		    PDF_show_boxed(myPDF, enhanced_text, x, y, 0, 0, "left", NULL);
Packit 0986c0
		} else {
Packit 0986c0
		    PDF_save(myPDF);
Packit 0986c0
		    PDF_translate(myPDF, x, y);
Packit 0986c0
		    PDF_rotate(myPDF, PDF_TextAngle);
Packit 0986c0
		    /* vertical justification*/
Packit 0986c0
		    PDF_translate(myPDF, 0, -(PDF_fontAscent-PDF_fontDescent)/2);
Packit 0986c0
		    PDF_show_boxed(myPDF, enhanced_text, 0, 0, 0, 0, "left", NULL);
Packit 0986c0
		    PDF_restore(myPDF);
Packit 0986c0
		}
Packit 0986c0
	    }
Packit 0986c0
	    if (ENHpdf_overprint == 1) {
Packit 0986c0
		PDF_xLast += stringlength * cos((double)PDF_TextAngle * M_PI_2/90.) / 2.;
Packit 0986c0
		PDF_yLast += stringlength * sin((double)PDF_TextAngle * M_PI_2/90.);
Packit 0986c0
	    } else if (ENHpdf_widthflag) {
Packit 0986c0
		PDF_xLast += stringlength * cos((double)PDF_TextAngle * M_PI_2/90.);
Packit 0986c0
		PDF_yLast += stringlength * sin((double)PDF_TextAngle * M_PI_2/90.);
Packit 0986c0
	    }
Packit 0986c0
	}
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
TERM_PUBLIC void
Packit 0986c0
ENHPDF_put_text(unsigned int x, unsigned int y, const char *str)
Packit 0986c0
{
Packit 0986c0
    char *original_string = (char *)str;
Packit 0986c0
Packit 0986c0
    if (ignore_enhanced_text) {
Packit 0986c0
	PDF_put_text(x,y,str);
Packit 0986c0
	return;
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    if (!str || !strlen(str))
Packit 0986c0
	return;
Packit 0986c0
Packit 0986c0
    /* if there are no magic characters, we should just be able
Packit 0986c0
     * punt the string to PDF_put_text()
Packit 0986c0
     */
Packit 0986c0
    if (!strpbrk(str, "{}^_@&~")) {
Packit 0986c0
	/* do something to ensure default font is selected */
Packit 0986c0
	PDF_put_text(x,y,str);
Packit 0986c0
	return;
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    PDF_move(x, y);
Packit 0986c0
    PDF_PathClose();
Packit 0986c0
    PDF_save(myPDF);
Packit 0986c0
Packit 0986c0
    /* FIXME - Is this the way to do it?????
Packit 0986c0
    if (PDF_TextAngle != 0)
Packit 0986c0
	ENHPDF_DEBUG(("currentpoint gsave translate %d rotate 0 0 moveto\n", PDF_TextAngle));
Packit 0986c0
     */
Packit 0986c0
Packit 0986c0
    /* set up the global variables needed by enhanced_recursion() */
Packit 0986c0
    enhanced_fontscale = PDF_fontscale;
Packit 0986c0
    strncpy(enhanced_escape_format,"%c",sizeof(enhanced_escape_format));
Packit 0986c0
Packit 0986c0
    ENHpdf_opened_string = FALSE;
Packit 0986c0
Packit 0986c0
    /* EAM - Software text justification requires two passes */
Packit 0986c0
    if (PDF_TextJust == RIGHT || PDF_TextJust == CENTRE)
Packit 0986c0
	ENHpdf_sizeonly = TRUE;
Packit 0986c0
Packit 0986c0
    /* Set the recursion going. We say to keep going until a
Packit 0986c0
     * closing brace, but we don't really expect to find one.
Packit 0986c0
     * If the return value is not the nul-terminator of the
Packit 0986c0
     * string, that can only mean that we did find an unmatched
Packit 0986c0
     * closing brace in the string. We increment past it (else
Packit 0986c0
     * we get stuck in an infinite loop) and try again.
Packit 0986c0
     */
Packit 0986c0
    while (*(str = enhanced_recursion((char *)str, TRUE,
Packit 0986c0
			PDF_fontNameCur, PDF_fontSizeCur * PDF_fontscale,
Packit 0986c0
			0.0, TRUE, TRUE, 0))) {
Packit 0986c0
	(term->enhanced_flush)();
Packit 0986c0
Packit 0986c0
	/* I think we can only get here if *str == '}' */
Packit 0986c0
	    enh_err_check(str);
Packit 0986c0
Packit 0986c0
	if (!*++str)
Packit 0986c0
	    break; /* end of string */
Packit 0986c0
Packit 0986c0
	/* else carry on and process the rest of the string */
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
    PDF_restore(myPDF);
Packit 0986c0
Packit 0986c0
    /* We can do text justification by running the entire top level string */
Packit 0986c0
    /* through 2 times, with the ENHpdf_sizeonly flag set the first time.   */
Packit 0986c0
    /* After seeing where the final position is, we then offset the start  */
Packit 0986c0
    /* point accordingly and run it again.                                 */
Packit 0986c0
    if (PDF_TextJust == RIGHT || PDF_TextJust == CENTRE) {
Packit 0986c0
	int justification = PDF_TextJust;
Packit 0986c0
	int x_offset = PDF_xLast - x;
Packit 0986c0
	int y_offset = 0;
Packit 0986c0
Packit 0986c0
	if (PDF_TextAngle != 0)
Packit 0986c0
	    y_offset = PDF_yLast - y;
Packit 0986c0
	PDF_TextJust = LEFT;
Packit 0986c0
	ENHpdf_sizeonly = FALSE;
Packit 0986c0
Packit 0986c0
	if (justification == RIGHT) {
Packit 0986c0
	    ENHPDF_put_text(x - x_offset, y - y_offset, original_string);
Packit 0986c0
	} else if (justification == CENTRE) {
Packit 0986c0
	    ENHPDF_put_text(x - x_offset/2, y - y_offset/2, original_string);
Packit 0986c0
	}
Packit 0986c0
	PDF_TextJust = justification;
Packit 0986c0
    }
Packit 0986c0
Packit 0986c0
}
Packit 0986c0
Packit 0986c0
#endif /* TERM_BODY */
Packit 0986c0
Packit 0986c0
#ifdef TERM_TABLE
Packit 0986c0
TERM_TABLE_START (pdf_driver)
Packit 0986c0
    "pdf", "PDF (Portable Document File) file driver",
Packit 0986c0
    0 /* xmax */ , 0 /* ymax */ , 0 /* vchar */ , 0 /* hchar */ ,
Packit 0986c0
    0 /* vtic */ , 0 /* htic */ ,
Packit 0986c0
    PDF_options, PDF_init, PDF_reset, PDF_text, null_scale, PDF_graphics,
Packit 0986c0
    PDF_move, PDF_vector, PDF_linetype, PDF_put_text, PDF_text_angle,
Packit 0986c0
    PDF_justify_text, PDF_point, do_arrow, PDF_set_font, do_pointsize,
Packit 0986c0
    TERM_BINARY|TERM_CAN_DASH|TERM_LINEWIDTH|TERM_FONTSCALE,
Packit 0986c0
    0 /* suspend */, 0 /* resume */ , PDF_boxfill, PDF_linewidth
Packit 0986c0
#   ifdef USE_MOUSE
Packit 0986c0
   , 0, 0, 0, 0, 0 /* no mouse support for pdf */
Packit 0986c0
#   endif
Packit 0986c0
   , PDF_make_palette,
Packit 0986c0
   PDF_previous_palette,
Packit 0986c0
   PDF_set_color,
Packit 0986c0
   PDF_filled_polygon
Packit 0986c0
   , PDF_image
Packit 0986c0
   , ENHPDF_OPEN, ENHPDF_FLUSH, do_enh_writec
Packit 0986c0
TERM_TABLE_END (pdf_driver)
Packit 0986c0
#undef LAST_TERM
Packit 0986c0
#define LAST_TERM pdf_driver
Packit 0986c0
#endif /* TERM_TABLE */
Packit 0986c0
Packit 0986c0
#endif /* TERM_PROTO_ONLY */
Packit 0986c0
Packit 0986c0
#ifdef TERM_HELP
Packit 0986c0
START_HELP(pdf)
Packit 0986c0
"1 pdf",
Packit 0986c0
"?commands set terminal pdf",
Packit 0986c0
"?set terminal pdf",
Packit 0986c0
"?set term pdf",
Packit 0986c0
"?terminal pdf",
Packit 0986c0
"?term pdf",
Packit 0986c0
"?pdf",
Packit 0986c0
" [DEPRECATED] This terminal uses the non-free library PDFlib (GmbH Munchen)"
Packit 0986c0
" to produce files in Portable Document Format. Unless you have a commercial",
Packit 0986c0
" license for PDFlib and need some special feature it provides you would do",
Packit 0986c0
" better to use the cairopdf terminal instead.  Gnuplot can also export PDF",
Packit 0986c0
" files from wxt or qt interactive terminal sessions.",
Packit 0986c0
"",
Packit 0986c0
" Syntax:",
Packit 0986c0
"       set terminal pdf {monochrome|color|colour}",
Packit 0986c0
"                        {{no}enhanced}",
Packit 0986c0
"                        {fname \"<font>\"} {fsize <fontsize>}",
Packit 0986c0
"                        {font \"<fontname>{,<fontsize>}\"} {fontscale <scale>}",
Packit 0986c0
"                        {linewidth <lw>} {rounded|butt}",
Packit 0986c0
"                        {dl <dashlength>}}",
Packit 0986c0
"                        {size <XX>{unit},<YY>{unit}}",
Packit 0986c0
"",
Packit 0986c0
" The default is to use a different color for each line type. Selecting",
Packit 0986c0
" `monochome` will use black for all linetypes, Even in in mono mode",
Packit 0986c0
" you can still use explicit colors for filled areas or linestyles.",
Packit 0986c0
"",
Packit 0986c0
" where <font> is the name of the default font to use (default Helvetica)",
Packit 0986c0
" and <fontsize> is the font size (in points, default 12).",
Packit 0986c0
" For help on which fonts are available or how to install new ones, please",
Packit 0986c0
" see the documentation for your local installation of pdflib.",
Packit 0986c0
"",
Packit 0986c0
" The `enhanced` option enables enhanced text processing features",
Packit 0986c0
" (subscripts, superscripts and mixed fonts). See `enhanced`.",
Packit 0986c0
"",
Packit 0986c0
" The width of all lines in the plot can be increased by the factor <n>",
Packit 0986c0
" specified in `linewidth`. Similarly `dashlength` is a multiplier for the",
Packit 0986c0
" default dash spacing.",
Packit 0986c0
"",
Packit 0986c0
" `rounded` sets line caps and line joins to be rounded; `butt` is the",
Packit 0986c0
" default, butt caps and mitered joins.",
Packit 0986c0
"",
Packit 0986c0
" The default size for PDF output is 5 inches by 3 inches. The `size` option",
Packit 0986c0
" changes this to whatever the user requests. By default the X and Y sizes",
Packit 0986c0
" are taken to be in inches, but other units are possible (currently only cm).",
Packit 0986c0
""
Packit 0986c0
END_HELP(pdf)
Packit 0986c0
#endif