X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=term%2Fpdf.trm;fp=term%2Fpdf.trm;h=582baffaf01cf2dbe362ad5965f63a19fd8f6c1e;hb=39ec1247a71f61152a4a7f502a30f06a3896c5da;hp=0000000000000000000000000000000000000000;hpb=06be459be4f5f6a7c6ff878e84f355fb2575caa8;p=gnuplot diff --git a/term/pdf.trm b/term/pdf.trm new file mode 100644 index 0000000..582baff --- /dev/null +++ b/term/pdf.trm @@ -0,0 +1,1712 @@ +/* Hello, Emacs, this is -*-C-*- + * $Id: pdf.trm,v 1.68.2.9 2008/12/12 07:14:11 sfeam Exp $ + */ + +/*------------------------------ + GNUPLOT - pdf.trm + + This file is included by ../term.c. + + This driver uses PDFlib from www.pdflib.com + + Author: + + Hans-Bernhard Br"oker + broeker@physik.rwth-aachen.de + + Licence: see the gnuplot copyright (to be merged into here...) + + Options: can #define PDF_DONT_COMPRESS to avoid PDF output + generated being compressed (by the 'deflate' algorithm as used + in 'zip' or 'gzip'). That helps in debugging. + +------------------------------*/ + +/* CODEME: Add patterned lines (?). */ + +/* PM3D support by Johannes Zellner , May-15-2002 */ +/* set_color fixes by Petr Mikulik , June-10-2002 */ +/* image support by Ethan A Merritt , March 2003 */ + +/* Text rotation 24-Jul-2002 Ethan A Merritt */ +/* Revised fill patterns 02-Apr-2003 Ethan A Merritt */ +/* Enhanced text mode support November 2003 Ethan A Merritt */ + +#include "driver.h" + +#ifdef TERM_REGISTER +register_term(pdf) +#endif + +#ifdef TERM_PROTO +TERM_PUBLIC void PDF_options __PROTO ((void)); +TERM_PUBLIC void PDF_init __PROTO ((void)); +TERM_PUBLIC void PDF_graphics __PROTO ((void)); +TERM_PUBLIC void PDF_text __PROTO ((void)); +TERM_PUBLIC void PDF_linetype __PROTO ((int linetype)); +TERM_PUBLIC void PDF_move __PROTO ((unsigned int x, unsigned int y)); +TERM_PUBLIC void PDF_vector __PROTO ((unsigned int x, unsigned int y)); +TERM_PUBLIC void PDF_put_text __PROTO ((unsigned int x, unsigned int y, const char *str)); +TERM_PUBLIC void PDF_reset __PROTO ((void)); +TERM_PUBLIC int PDF_justify_text __PROTO ((enum JUSTIFY mode)); +TERM_PUBLIC int PDF_text_angle __PROTO ((int ang)); +TERM_PUBLIC void PDF_point __PROTO ((unsigned int x, unsigned int y, int pointstyle)); +TERM_PUBLIC int PDF_set_font __PROTO ((const char *font)); +TERM_PUBLIC void PDF_boxfill __PROTO((int style, unsigned int x1, unsigned int y1, unsigned int width, unsigned int height)); +TERM_PUBLIC void PDF_linewidth __PROTO ((double linewidth)); +TERM_PUBLIC int PDF_make_palette __PROTO((t_sm_palette *)); +TERM_PUBLIC void PDF_previous_palette __PROTO((void)); +TERM_PUBLIC void PDF_set_color __PROTO((t_colorspec *)); +#ifdef WITH_IMAGE +TERM_PUBLIC void PDF_image __PROTO((unsigned, unsigned, coordval *, gpiPoint *, t_imagecolor)); +#endif + +TERM_PUBLIC void PDF_filled_polygon __PROTO((int, gpiPoint *)); + +/* To support "set term png enhanced" */ +TERM_PUBLIC void ENHPDF_put_text __PROTO((unsigned int x, unsigned int y, const char *str)); +TERM_PUBLIC void ENHPDF_OPEN __PROTO((char * fontname, double fontsize, + double base, TBOOLEAN widthflag, TBOOLEAN showflag, + int overprint)); +TERM_PUBLIC void ENHPDF_FLUSH __PROTO((void)); + +#define PDF_NUM_POINTTYPES 75 /* number of point symbol types not counting the dot */ + +#define PDF_RESOLUTION (20) /* number of terminal pixels per pt */ +#define PDF_XMAX (5*72*PDF_RESOLUTION) /* 5 inches, 72 pt/inch */ +#define PDF_YMAX (3*72*PDF_RESOLUTION) /* 3 inches, 72 pt/inch */ + +static TBOOLEAN pdf_explicit_size = FALSE; +static size_units pdf_explicit_units = INCHES; + +#endif /* TERM_PROTO */ + +#ifndef TERM_PROTO_ONLY +#ifdef TERM_BODY + +#include + +static PDF *myPDF = NULL; + +static unsigned int PDF_xLast = UINT_MAX; /* current pen horizontal position*/ +static unsigned int PDF_yLast = UINT_MAX; /* current pen vertical position*/ + +static int PDF_LineType = LT_UNDEFINED; /* current line type*/ +static int PDF_LineCap = 0; /* Butt ends */ +static double PDF_LineWidth = 1.0; /* current line width*/ +static int PDF_TextAngle = 0; /* current text orientation*/ +static enum JUSTIFY PDF_TextJust = LEFT; /* current text justification*/ +static double PDF_linewidth_factor = 1.0; /* multiplier for line width */ +static double PDF_dashlength_factor = 1.0; /* multiplier for dash length */ +static TBOOLEAN PDF_dashedlines = FALSE; /* solid or dashed? */ +static TBOOLEAN PDF_monochrome = FALSE; /* default all linetypes to black */ +static rgb_color PDF_current_rgb = {0.,0.,0.}; /* Last color set */ +static double PDF_current_gray = 0.0; /* Last color set (mono version) */ + +/* default text font family: */ +static char PDF_fontNameDef[MAX_ID_LEN + 1] = "Helvetica"; +static double PDF_fontSizeDef = 6; /* default text size*/ +/* current text font family: */ +static char PDF_fontNameCur[MAX_ID_LEN + 1] = "Helvetica"; +static double PDF_fontSizeCur = 6; /* current text size*/ + +static TBOOLEAN PDF_pageIsOpen = FALSE; /* already started a page ?? */ +static TBOOLEAN PDF_pathIsOpen = FALSE; /* open path flag*/ + +static int PDF_fontAscent = 0; /* estimated current font ascent*/ +static int PDF_fontDescent = 0; /* estimated current font descent*/ +static int PDF_fontLeading = 0; /* estimated current font leading*/ +static int PDF_fontAvWidth = 0; /* estimated current font char average width*/ +static int PDF_currentFontHandle; /* Needed for exhanced text mode */ + +static short PDF_Pen_RealID __PROTO ((int)); +static void PDF_PathOpen __PROTO ((void)); +static void PDF_PathClose __PROTO ((void)); +static void PDF_SetFont __PROTO ((void)); +static void PDF_DefinePatterns __PROTO((void)); +enum { PDF_patterns = 7 }; +static int PDF_patternHandles[PDF_patterns]; + +#ifndef HAVE_NODASH_LIBPDF +/* Description of dash patterns (same as those in post.trm) */ +static int dash1[] = {8, 8}; +static int dash2[] = {4, 6}; +static int dash3[] = {2, 3}; +static int dash4[] = {12, 4, 2, 4}; +static int dash5[] = {6, 6, 2, 6}; +static int dash6[] = {4, 4, 4, 12}; +static int dash7[] = {1, 4, 12, 4, 1, 4}; +#endif + +/*------------------------ helper functions -------------------*/ + +static short +PDF_Pen_RealID (int inPenCode) +{ + if (inPenCode >= 12) + inPenCode %= 12; /* normalize pen code*/ + if (inPenCode <= LT_NODRAW) + inPenCode = LT_NODRAW; + + return (inPenCode + 2); +} + +/* Functions to ensure that as many move() and vector() calls as + * possible get converted into a single long 'path', before closing it + * with a stroke or similar command. */ +static void +PDF_PathOpen () +{ + PDF_pathIsOpen = TRUE; +} + +static void +PDF_PathClose () +{ + if (PDF_pathIsOpen) { + PDF_stroke(myPDF); + + PDF_pathIsOpen = FALSE; + } +} + +/* Helper function to deal with switching over to a newly selected font. + * For now, this does not try to embed fonts into the PDF file. + * We would like to allow UTF-8 fonts via + font_handle = PDF_findfont(myPDF, PDF_fontNameCur, "unicode", 0); + * but this is not supported by the free-as-in-beer PDFlib Lite. + */ +static void +PDF_SetFont () +{ + int font_handle; + const char *pdfenc = "host"; + + /* Allow graceful failure */ + PDF_set_parameter(myPDF, "fontwarning", "false"); + + /* LCB : Symbol and ZapfDingbats should use "builtin" encoding */ + if ( (strcmp(PDF_fontNameCur,"Symbol") == 0) || + (strcmp(PDF_fontNameCur,"ZapfDingbats") == 0) ) { + pdfenc = "builtin"; + } else if (encoding == S_ENC_ISO8859_1) { + pdfenc = "iso8859-1"; + } else if (encoding == S_ENC_ISO8859_2) { + pdfenc = "iso8859-2"; + } else if (encoding == S_ENC_ISO8859_15) { + pdfenc = "iso8859-15"; + } else if (encoding == S_ENC_CP1250) { + pdfenc = "cp1250"; + } + + font_handle = PDF_findfont(myPDF, PDF_fontNameCur, pdfenc, 0); + + if (font_handle == -1 && strcmp(pdfenc, "host")) { + fprintf(stderr,"Couldn't find font %s in encoding %s, trying \"host\"\n", + PDF_fontNameCur, pdfenc); + font_handle = PDF_findfont(myPDF, PDF_fontNameCur, "host", 0); + } + + if (font_handle == -1) { + font_handle = PDF_findfont(myPDF, "Times-Roman", "host", 0); + fprintf(stderr,"Couldn't find font %s, falling back to Times-Roman\n", PDF_fontNameCur); + } + + PDF_setfont(myPDF, font_handle, PDF_fontSizeCur * PDF_RESOLUTION); + + /* Ask PDFlib for the actual numbers */ + PDF_fontAscent = (int) (PDF_RESOLUTION * PDF_fontSizeCur * PDF_get_value(myPDF, "ascender", 0)); + PDF_fontDescent = (int) (- PDF_RESOLUTION * PDF_fontSizeCur * PDF_get_value(myPDF, "descender", 0)); + PDF_fontLeading = (int) (PDF_RESOLUTION * PDF_fontSizeCur * 0.25); + + /* Assume this particular string is a somewhat reasonable typical + * output, for getting at the average character width */ + PDF_fontAvWidth = (int) + (PDF_RESOLUTION * PDF_stringwidth(myPDF, "01234567890123456789", + font_handle, PDF_fontSizeCur) + / 20.0); + PDF_currentFontHandle = font_handle; + +} + +#if !HAVE_OLD_LIBPDF +static void +PDF_DefinePatterns() +{ + int i; + + /* EAM April 2003 - Rearrange patterns to maximize contrast in mono. + * Because of the finite linewidth, each pattern must include line + * fragments at the "empty" corners. + */ + for (i=0; iput_text = ENHPDF_put_text; + term->flags |= TERM_ENHANCED_TEXT; + continue; + } else if (almost_equals(c_token, "noenh$anced")) { + c_token++; + term->put_text = PDF_put_text; + term->flags &= ~TERM_ENHANCED_TEXT; + continue; + } + + if (almost_equals(c_token, "fn$ame") || almost_equals(c_token, "font")) { + char *s, *comma; + c_token++; + + if (!(s = try_to_get_string())) + int_error(c_token,"fname: expecting font name"); + comma = strrchr(s,','); + if (comma && (1 == sscanf(comma+1,"%lf",&PDF_fontSizeDef))) + *comma = '\0'; + if (*s) + strncpy(PDF_fontNameDef, s, sizeof(PDF_fontNameDef)); + free(s); + continue; + } + + if (almost_equals(c_token, "fs$ize")) { + c_token++; + + if (END_OF_COMMAND) + int_error(c_token,"fsize: expecting font size"); + PDF_fontSizeDef = real (const_express (&a)); + continue; + } + + if (equals(c_token, "lw") || almost_equals(c_token, "linew$idth")) { + c_token++; + + if (END_OF_COMMAND) + int_error(c_token, "expecting line width"); + PDF_linewidth_factor = real (const_express (&a)); + if (PDF_linewidth_factor <= 0) + PDF_linewidth_factor = 0.1; + continue; + } + + if (almost_equals(c_token, "rou$nded")) { + c_token++; + PDF_LineCap = 1; + continue; + } + + if (equals(c_token, "butt")) { + PDF_LineCap = 0; + continue; + } + + if (equals(c_token, "color") || almost_equals(c_token, "col$our")) { + c_token++; + PDF_monochrome = FALSE; + continue; + } + + if (almost_equals(c_token, "mono$chrome")) { + c_token++; + PDF_monochrome = TRUE; + continue; + } + + if (equals(c_token, "dl") || almost_equals(c_token, "dashl$ength")) { + c_token++; + if (END_OF_COMMAND) + int_error(c_token, "expecting dashlength multiplier"); + PDF_dashlength_factor = real(const_express(&a)); + if (PDF_dashlength_factor < 0.0) + PDF_dashlength_factor = 1.0; + continue; + } + + if (equals(c_token, "solid")) { + c_token++; + PDF_dashedlines = FALSE; + continue; + } + + if (equals(c_token, "size")) { + float xmax_t, ymax_t; + c_token++; + pdf_explicit_size = TRUE; + pdf_explicit_units = parse_term_size(&xmax_t, &ymax_t, INCHES); + term->xmax = xmax_t*PDF_RESOLUTION*72./gp_resolution; + term->ymax = ymax_t*PDF_RESOLUTION*72./gp_resolution; + break; + } + +#ifdef HAVE_NODASH_LIBPDF + int_warn(NO_CARET,"gnuplot was linked against a version of pdflib with no dash or pattern support"); +#else + if (almost_equals(c_token, "dash$ed")) { + c_token++; + PDF_dashedlines = TRUE; + continue; + } +#endif + + int_error(c_token, "unexpected text at end of command"); + + } + + /* Save options back into options string in normalized format */ + sprintf(term_options, "%s%s fname '%s' fsize %g linewidth %3.1f %s ", + PDF_monochrome ? "monochrome " : " ", + term->put_text == ENHPDF_put_text ? "enhanced" : "noenhanced", + PDF_fontNameDef, PDF_fontSizeDef, PDF_linewidth_factor, + PDF_LineCap == 1 ? "rounded" : ""); + if (PDF_dashedlines) + sprintf(&(term_options[strlen(term_options)]), "dashed dl %3.1f", + PDF_dashlength_factor); + if (pdf_explicit_size) { + if (pdf_explicit_units == CM) + sprintf(&(term_options[strlen(term_options)]), "size %.2fcm, %.2fcm ", + 2.54*(float)term->xmax/(72.*PDF_RESOLUTION), + 2.54*(float)term->ymax/(72.*PDF_RESOLUTION)); + else + sprintf(&(term_options[strlen(term_options)]), "size %.2fin, %.2fin ", + (float)term->xmax/(72.*PDF_RESOLUTION), + (float)term->ymax/(72.*PDF_RESOLUTION)); + } +} + + +TERM_PUBLIC void +PDF_init () +{ + static TBOOLEAN PDFlib_booted = FALSE; + char *gpversionstring; + char *username; + char *timedate; + time_t now; + + if (!PDFlib_booted) { + PDF_boot(); + PDFlib_booted = TRUE; + } + + if (!myPDF) + myPDF = PDF_new(); + + /*open new PDF file */ +#ifdef HAVE_LIBPDF_OPEN_FILE + if (PDF_open_file(myPDF, outstr) == -1) +#else + if (PDF_begin_document(myPDF, outstr?outstr:"-", 0, + "compatibility=1.4") == -1) +#endif /* HAVE_LIBPDF_OPEN_FILE */ + int_error(NO_CARET, "Error:cannot open PDF file .\n"); + +#ifdef PDF_DONT_COMPRESS + /* for easier debugging of the output, turn off PDF stream + * compression */ + PDF_set_value(myPDF, "compress", 0); +#endif + + gpversionstring = gp_alloc(20 + strlen(gnuplot_version) + + strlen(gnuplot_patchlevel) + 1, "PDF_init"); + sprintf(gpversionstring,"gnuplot %s patchlevel %s", + gnuplot_version, gnuplot_patchlevel); + + time(&now); + timedate=asctime(localtime(&now)); + timedate[strlen(timedate)-1]='\0'; + + PDF_set_info(myPDF,"Creator",gpversionstring); + + username=getusername(); + if (username) { + PDF_set_info(myPDF,"Author",username); + free(username); + } + + if (outstr) + PDF_set_info(myPDF,"Title",outstr); /* FIXME: use 'set title', if any? */ + PDF_set_info(myPDF,"Subject","gnuplot plot"); + + if (gpversionstring) + free(gpversionstring); + + PDF_LineType = LT_UNDEFINED; + + /* set current font to default */ + strcpy(PDF_fontNameCur, PDF_fontNameDef); + PDF_fontSizeCur = PDF_fontSizeDef; + +#if !HAVE_OLD_LIBPDF + PDF_DefinePatterns(); +#endif + + /* Have to start the first page now, in order to know the actual + * size of the selected font */ + PDF_graphics(); + + /* set h_char, v_char*/ + term->h_char = PDF_fontAvWidth; + term->v_char = (PDF_fontAscent + PDF_fontDescent + PDF_fontLeading); + + /* set h_tic, v_tic*/ + term->h_tic = term->v_tic = 3 * PDF_RESOLUTION; + + /* initialize terminal's pointsize from "set pointsize" value */ + term_pointsize = pointsize; + + /* Initialize other default settings */ + PDF_setlinecap(myPDF, PDF_LineCap); + PDF_setlinejoin(myPDF, PDF_LineCap); /* round+round or butt+mitre */ +} + + +TERM_PUBLIC void +PDF_graphics () +{ + if (PDF_pageIsOpen) + return; /* already open --> nothing to do */ + + PDF_pathIsOpen = FALSE; + PDF_xLast = PDF_yLast = UINT_MAX; + + /* set size of canvas */ + if (!pdf_explicit_size) { + term->xmax = PDF_XMAX; + term->ymax = PDF_YMAX; + } + + PDF_begin_page(myPDF, (double)term->xmax / PDF_RESOLUTION, + (double)term->ymax / PDF_RESOLUTION); + PDF_scale(myPDF, 1.0/PDF_RESOLUTION, 1.0/PDF_RESOLUTION); + if (title.text && title.text[0]) + /* a title has been set --> use it as the bookmark name, too */ + PDF_add_bookmark(myPDF, title.text, 0, 1); + PDF_pageIsOpen = TRUE; + + PDF_SetFont(); +} + + +TERM_PUBLIC void +PDF_text () +{ + PDF_PathClose(); + PDF_end_page(myPDF); + PDF_pageIsOpen = FALSE; +} + + +TERM_PUBLIC void +PDF_reset () +{ + assert(PDF_pageIsOpen == FALSE); +#ifdef HAVE_LIBPDF_OPEN_FILE + PDF_close(myPDF); +#else + PDF_end_document(myPDF, ""); +#endif /* HAVE_LIBPDF_OPEN_FILE */ + PDF_delete(myPDF); + myPDF = NULL; +} + + +TERM_PUBLIC void +PDF_linetype (int linetype) +{ + int dash = linetype % 8; + + linetype = PDF_Pen_RealID(linetype); + if (linetype == PDF_LineType) + return; + + PDF_PathClose (); + PDF_LineType = linetype; + + if (PDF_monochrome) { + PDF_current_gray = 0.0; + PDF_setgray(myPDF, PDF_current_gray); + } else { + struct rgb *this_color = web_color_rgbs + 1 + linetype; + PDF_current_rgb.r = this_color->r / 255.0; + PDF_current_rgb.g = this_color->g / 255.0; + PDF_current_rgb.b = this_color->b / 255.0; + PDF_setrgbcolor(myPDF, PDF_current_rgb.r, PDF_current_rgb.g, PDF_current_rgb.b); + } + +#ifndef HAVE_NODASH_LIBPDF + if (PDF_dashedlines) { + char dashtype[64]; + float dl = 8.0 * PDF_dashlength_factor; + + switch (dash) { + default: + case 0: PDF_setdash(myPDF, 0.0, 0.0); + return; + case 1: sprintf(dashtype,"dasharray={%4.1f %4.1f}", + dl*dash1[0],dl*dash1[1]); + break; + case 2: sprintf(dashtype,"dasharray={%4.1f %4.1f}", + dl*dash2[0],dl*dash2[1]); + break; + case 3: sprintf(dashtype,"dasharray={%4.1f %4.1f}", + dl*dash3[0],dl*dash3[1]); + break; + case 4: sprintf(dashtype,"dasharray={%4.1f %4.1f %4.1f %4.1f}", + dl*dash4[0],dl*dash4[1],dl*dash4[2],dl*dash4[3]); + break; + case 5: sprintf(dashtype,"dasharray={%4.1f %4.1f %4.1f %4.1f}", + dl*dash5[0],dl*dash5[1],dl*dash5[2],dl*dash5[3]); + break; + case 6: sprintf(dashtype,"dasharray={%4.1f %4.1f %4.1f %4.1f}", + dl*dash6[0],dl*dash6[1],dl*dash6[2],dl*dash6[3]); + break; + case 7: sprintf(dashtype,"dasharray={%4.1f %4.1f %4.1f %4.1f %4.1f %4.1f}", + dl*dash7[0],dl*dash7[1],dl*dash7[2],dl*dash7[3],dl*dash7[4],dl*dash7[5]); + break; + } + PDF_setdashpattern(myPDF,dashtype); + } +#endif + +} + + +TERM_PUBLIC void +PDF_linewidth (double linewidth) +{ + PDF_PathClose(); + PDF_LineWidth = PDF_RESOLUTION * PDF_linewidth_factor * linewidth / 4.0; + if (PDF_LineWidth < 0.1) + PDF_LineWidth = 0.1; + PDF_setlinewidth(myPDF, PDF_LineWidth); +} + + +TERM_PUBLIC void +PDF_move (unsigned int x, unsigned int y) +{ + if (PDF_pathIsOpen && x == PDF_xLast && y == PDF_yLast) + return; + + PDF_PathOpen (); + PDF_moveto(myPDF, x, y); + + PDF_xLast = x; + PDF_yLast = y; +} + + +TERM_PUBLIC void +PDF_vector (unsigned int x, unsigned int y) +{ + if (PDF_pathIsOpen && x == PDF_xLast && y == PDF_yLast) + return; + + PDF_PathOpen (); + PDF_lineto(myPDF, x, y); + + PDF_xLast = x; + PDF_yLast = y; +} + +/* Helper function. Many symbols have an additional dot in their + * center, so isolate its drawing into a separate function. */ +static GP_INLINE void +PDF_dot (unsigned int x, unsigned int y) +{ + /* Imitate PS's way of creating a small dot by a zero-length line + * segment with rounded endpoints */ + PDF_setlinecap(myPDF, 1); /* rounded ends */ + PDF_moveto(myPDF, x, y); + PDF_lineto(myPDF, x, y); + PDF_stroke(myPDF); + PDF_setlinecap(myPDF, PDF_LineCap); /* restore ends */ +} + + +TERM_PUBLIC void +PDF_point (unsigned int x, unsigned int y, int number) +{ + PDF_PathClose (); + PDF_save(myPDF); + + if (number < 0) { + /* Treat all negative point sizes as dots */ + PDF_dot(x, y); + } else { + /* Change coordinate system so the point symbols themselves + * can be drawn without depending on position or size (--> + * better compression and less coding for gnuplot) */ + /* NB: I use the do_pointsize() default implementation, which + * just stores the last set pointsize into `term_pointsize', + * to avoid introducing another static driver-local variable + * */ + PDF_translate(myPDF, x, y); + PDF_scale(myPDF, term->h_tic / 2.0 * term_pointsize, + term->v_tic / 2.0 * term_pointsize); + /* Correct linewidth to counter the scaling effect --- assume + * h_tic is usable, to avoid having to average h_ and v_tic */ + PDF_setlinewidth(myPDF, + PDF_LineWidth / (term->h_tic / 2.0 * term_pointsize)); + switch (number %= PDF_NUM_POINTTYPES) { + case 0: /* Plus */ + PDF_moveto(myPDF, -1, 0); + PDF_lineto(myPDF, 1, 0); + PDF_moveto(myPDF, 0, -1); + PDF_lineto(myPDF, 0, 1); + PDF_stroke(myPDF); + break; + case 2: /* Star */ + PDF_moveto(myPDF, -1, 0); + PDF_lineto(myPDF, 1, 0); + PDF_moveto(myPDF, 0, -1); + PDF_lineto(myPDF, 0, 1); + /* FALLTHROUGH */ + case 1: /* Cross */ + PDF_moveto(myPDF, -1, -1); + PDF_lineto(myPDF, 1, 1); + PDF_moveto(myPDF, 1, -1); + PDF_lineto(myPDF, -1, 1); + PDF_stroke(myPDF); + break; + +/* For each x = 0..5, 4 shapes are defined: + * 3 + 2*x --> hollow symbol with a dot at its center + * 4 + 2*x --> solid symbol filled in linetype's color + * 63 + x --> hollow symbol without the center dot + * 69 + x --> symbol filled with white --> opaque symbol */ + + case 63+0: /* BoxEmpty */ + case 3+2*0: /* Box */ + PDF_moveto(myPDF, -1, -1); + PDF_lineto(myPDF, 1, -1); + PDF_lineto(myPDF, 1, 1); + PDF_lineto(myPDF, -1, 1); + PDF_closepath_stroke(myPDF); + if (number == 3) PDF_dot(0,0); + break; + case 69+0: /* BoxWhitefilled */ + PDF_setgray_fill(myPDF, 1); + /* FALLTHROUGH */ + case 4+2*0: /* BoxFilled */ + PDF_moveto(myPDF, -1, -1); + PDF_lineto(myPDF, 1, -1); + PDF_lineto(myPDF, 1, 1); + PDF_lineto(myPDF, -1, 1); + PDF_closepath_fill_stroke(myPDF); + break; + + case 63+1: /* CircleEmpty */ + case 3+2*1: /* Circle */ + PDF_circle(myPDF, 0, 0, 1); + PDF_stroke(myPDF); + if (number == 5) PDF_dot(0,0); + break; + case 69+1: /* CircleWhitefilled */ + PDF_setgray_fill(myPDF, 1); + /* FALLTHROUGH */ + case 4+2*1: /* CircleFilled */ + PDF_circle(myPDF, 0, 0, 1); + PDF_fill_stroke(myPDF); + break; + + case 63+2: /* TriangleUpEmpty */ + case 3+2*2: /* TriangleUp */ + PDF_moveto(myPDF, 0, 1.12); + PDF_lineto(myPDF, -1, -0.5); + PDF_lineto(myPDF, 1, -0.5); + PDF_closepath_stroke(myPDF); + if (number == 7) PDF_dot(0,0); + break; + case 69+2: /* TriangleUpWhitefilled */ + PDF_setgray_fill(myPDF, 1); + /* FALLTHROUGH */ + case 4+2*2: /* TriangleUpFilled */ + PDF_moveto(myPDF, 0, 1.12); + PDF_lineto(myPDF, -1, -0.5); + PDF_lineto(myPDF, 1, -0.5); + PDF_closepath_fill_stroke(myPDF); + break; + + case 63+3: /* TriangleDownEmpty */ + case 3+2*3: /* TriangleDown */ + PDF_moveto(myPDF, 0, -1.12); + PDF_lineto(myPDF, -1, 0.5); + PDF_lineto(myPDF, 1, 0.5); + PDF_closepath_stroke(myPDF); + if (number == 9) PDF_dot(0,0); + break; + case 69+3: /* TriangleDownWhitefilled */ + PDF_setgray_fill(myPDF, 1); + /* FALLTHROUGH */ + case 4+2*3: /* TriangleDownFilled */ + PDF_moveto(myPDF, 0, -1.12); + PDF_lineto(myPDF, -1, 0.5); + PDF_lineto(myPDF, 1, 0.5); + PDF_closepath_fill_stroke(myPDF); + break; + + case 63+4: /* DiamondEmpty */ + case 3+2*4: /* Diamond */ + PDF_moveto(myPDF, 0, -1); + PDF_lineto(myPDF, 1, 0); + PDF_lineto(myPDF, 0, 1); + PDF_lineto(myPDF, -1, 0); + PDF_closepath_stroke(myPDF); + if (number == 11) PDF_dot(0,0); + break; + case 69+4: /* DiamondWhitefilled */ + PDF_setgray_fill(myPDF, 1); + /* FALLTHROUGH */ + case 4+2*4: /* DiamondFilled */ + PDF_moveto(myPDF, 0, -1); + PDF_lineto(myPDF, 1, 0); + PDF_lineto(myPDF, 0, 1); + PDF_lineto(myPDF, -1, 0); + PDF_closepath_fill_stroke(myPDF); + break; + + case 63+5: /* PentagonEmpty */ + case 3+2*5: /* Pentagon */ + PDF_moveto(myPDF, 0, 1); + PDF_lineto(myPDF, -0.95, 0.31); + PDF_lineto(myPDF, -0.58, -0.81); + PDF_lineto(myPDF, +0.58, -0.81); + PDF_lineto(myPDF, +0.95, 0.31); + PDF_closepath_stroke(myPDF); + if (number == 13) PDF_dot(0,0); + break; + case 69+5: /* PentagonWhitefilled */ + PDF_setgray_fill(myPDF, 1); + /* FALLTHROUGH */ + case 4+2*5: /* PentagonFilled */ + PDF_moveto(myPDF, 0, 1); + PDF_lineto(myPDF, -0.95, 0.31); + PDF_lineto(myPDF, -0.58, -0.81); + PDF_lineto(myPDF, +0.58, -0.81); + PDF_lineto(myPDF, +0.95, 0.31); + PDF_closepath_fill_stroke(myPDF); + break; + +/* 15 + (0..15): circles with varying parts of'em filled. The added + * number is a bit-pattern of the 4 quadrants: 1 signals a quadrant + * filled */ + case 15+0: + PDF_moveto(myPDF, 0, 0); + PDF_lineto(myPDF, 0, 1); + PDF_arc(myPDF, 0, 0, 1, 90, 360+90); + PDF_closepath_stroke(myPDF); + break; + +/* Generalize common code into a macro... */ +#define CIRCLE_SINGLE_PIESLICE(x, y, angle1, angle2) \ + PDF_moveto(myPDF, 0, 0); \ + PDF_lineto(myPDF, (x), (y)); \ + PDF_arc(myPDF, 0, 0, 1, (angle1), (angle2)); \ + PDF_lineto(myPDF, 0, 0); \ + PDF_closepath(myPDF); \ + PDF_fill_stroke(myPDF); \ + PDF_arc(myPDF, 0, 0, 1, (angle2), (angle1) + 360); \ + PDF_stroke(myPDF); \ + break; + +#define CIRCLE_SINGLE_QUADRANT(x, y, angle) \ + CIRCLE_SINGLE_PIESLICE(x, y, angle, angle+90); + case 15+1: + CIRCLE_SINGLE_QUADRANT(1, 0, 0); + case 15+2: + CIRCLE_SINGLE_QUADRANT(0, 1, 90); + case 15+4: + CIRCLE_SINGLE_QUADRANT(-1, 0, 180); + case 15+8: + CIRCLE_SINGLE_QUADRANT(0, -1, 270); +#undef CIRCLE_SINGLE_QUADRANT + +#define CIRCLE_TWO_NEIGHBOR_QUADRANTS(x, y, angle) \ + CIRCLE_SINGLE_PIESLICE(x, y, angle, angle+180) + case 15+3: + CIRCLE_TWO_NEIGHBOR_QUADRANTS(1, 0, 0); + case 15+6: + CIRCLE_TWO_NEIGHBOR_QUADRANTS(0, 1, 90); + case 15+12: + CIRCLE_TWO_NEIGHBOR_QUADRANTS(-1, 0, 180); + case 15+9: + CIRCLE_TWO_NEIGHBOR_QUADRANTS(0, -1, 270); +#undef CIRCLE_TWO_NEIGHBOR_QUADRANTS + +#define CIRCLE_TWO_OPPOSING_QUADRANTS(x, y, angle) \ + PDF_moveto(myPDF, 0, 0); \ + PDF_lineto(myPDF, x, y); \ + PDF_arc(myPDF, 0, 0, 1, angle, angle + 90); \ + PDF_lineto(myPDF, 0, 0); \ + PDF_fill_stroke(myPDF); \ + PDF_moveto(myPDF, 0, 0); \ + PDF_lineto(myPDF, -x, -y); \ + PDF_arc(myPDF, 0, 0, 1, angle + 180, angle + 270); \ + PDF_lineto(myPDF, 0, 0); \ + PDF_fill_stroke(myPDF); \ + PDF_arc(myPDF, 0, 0, 1, angle + 90, angle + 360); \ + PDF_stroke(myPDF); \ + break; + case 15+5: + CIRCLE_TWO_OPPOSING_QUADRANTS(1, 0, 0); + case 15+10: + CIRCLE_TWO_OPPOSING_QUADRANTS(0, 1, 90); +#undef CIRCLE_TWO_OPPOSING_QUADRANTS + +#define CIRCLE_THREE_QUADRANTS(x, y, angle) \ + CIRCLE_SINGLE_PIESLICE(x, y, angle, angle+270) + case 15+7: + CIRCLE_THREE_QUADRANTS(1, 0, 0); + case 15+14: + CIRCLE_THREE_QUADRANTS(0, 1, 90); + case 15+13: + CIRCLE_THREE_QUADRANTS(-1, 0, 180); + case 15+11: + CIRCLE_THREE_QUADRANTS(0, -1, 270); +#undef CIRCLE_THREE_QUADRANTS +#undef CIRCLE_SINGLE_PIESLICE + + case 15+15: + PDF_circle(myPDF, 0, 0, 1); + PDF_closepath_fill_stroke(myPDF); + break; + + +/*************************************************************************/ +/* 31 + (0..15): squares with different quadrants of them filled in. */ +/*************************************************************************/ +/*************************************************************************/ +/* 47 + (0..15): diamonds with filled quadrants as given by bit pattern */ +/* Diamonds are drawn as squares rotated by 45 degrees, so can use + * fall-through from diamond to squares, and re-use some macros. */ +/*************************************************************************/ + case 47+0: + PDF_rotate(myPDF, 45); + /* FALLTHROUGH */ + case 31+0: + PDF_moveto(myPDF, 0, 0); + PDF_lineto(myPDF, 0, 1); + PDF_lineto(myPDF, -1, 1); + PDF_lineto(myPDF, -1, -1); + PDF_lineto(myPDF, 1, -1); + PDF_lineto(myPDF, 1, 1); + PDF_lineto(myPDF, 0, 1); + PDF_stroke(myPDF); + break; + + case 47+15: + PDF_rotate(myPDF, 45); + /* FALLTHROUGH */ + case 31+15: + PDF_moveto(myPDF, -1, 1); + PDF_lineto(myPDF, -1, -1); + PDF_lineto(myPDF, 1, -1); + PDF_lineto(myPDF, 1, 1); + PDF_closepath_fill_stroke(myPDF); + break; + +/* macros defining shapes of the partly filled symbols. Done by + * rotating the starting point (x0, y0) by 90 degrees or 45 degrees + * (with length adjustment). The rotations can be done without + * trigonometric function calls, since their values are known: + * cos(90)=0, sin(90)=1, cos(45)=sin(45)=1/sqrt(2). A good compiler + * should be able to optimize away all the local variables and + * loops... */ + +#define SQUARE_SINGLE_PIESLICE(x0, y0, quadrants) \ + { \ + int quadrant = 0; \ + int x= x0, y=y0; \ + PDF_moveto(myPDF, 0, 0); \ + PDF_lineto(myPDF, x, y); \ + /* poor man's rotation by 45 and 90 degrees around the \ + * square's outline. */ \ + while (quadrant++ < quadrants) { \ + int dummy; \ + PDF_lineto(myPDF, x-y, x+y); \ + dummy = x; x = -y; y = dummy; \ + } \ + PDF_lineto(myPDF, x, y); \ + PDF_closepath_fill_stroke(myPDF); \ + PDF_moveto(myPDF, x, y); \ + while (quadrant++ <= 4) { \ + int dummy; \ + PDF_lineto(myPDF, x-y, x+y); \ + dummy = x; x = -y; y = dummy; \ + } \ + PDF_lineto(myPDF, x, y); \ + PDF_stroke(myPDF); \ + } \ + break; + +#define SQUARE_TWO_OPPOSING_QUADRANTS(x0, y0, angle) \ + { \ + int x = x0, y = y0, dummy; \ + int counter = 0; \ + \ + while (counter++ < 2) { \ + PDF_moveto(myPDF, 0, 0); \ + PDF_lineto(myPDF, x, y); \ + PDF_lineto(myPDF, x-y, x+y); \ + dummy = x; x = -y; y = dummy; \ + PDF_lineto(myPDF, x, y); \ + PDF_closepath_fill_stroke(myPDF); \ + \ + PDF_moveto(myPDF, x, y); \ + PDF_lineto(myPDF, x-y, x+y); \ + dummy = x; x = -y; y = dummy; \ + PDF_lineto(myPDF, x, y); \ + PDF_stroke(myPDF); \ + } \ + break; \ + } + +/* Macros for diamonds just prepend the rotation and then call those + * for squares: */ +#define DIAMOND_SINGLE_PIESLICE(x, y, quadrants) \ + PDF_rotate(myPDF, 45); \ + SQUARE_SINGLE_PIESLICE(x, y, quadrants); +#define DIAMOND_TWO_OPPOSING_QUADRANTS(x, y, angle) \ + PDF_rotate(myPDF, 45); \ + SQUARE_TWO_OPPOSING_QUADRANTS(x, y, angle); + +/* ... and now all the individual cases. The 'angle' arguments' are + * purely for the sake of easing cut'n'paste with the circle case */ +#define SQUARE_SINGLE_QUADRANT(x, y, angle) \ + SQUARE_SINGLE_PIESLICE(x, y, 1); + case 31+1: + SQUARE_SINGLE_QUADRANT(1, 0, 0); + case 31+2: + SQUARE_SINGLE_QUADRANT(0, 1, 90); + case 31+4: + SQUARE_SINGLE_QUADRANT(-1, 0, 180); + case 31+8: + SQUARE_SINGLE_QUADRANT(0, -1, 270); +#undef SQUARE_SINGLE_QUADRANT + +#define SQUARE_TWO_NEIGHBOR_QUADRANTS(x, y, angle) \ + SQUARE_SINGLE_PIESLICE(x, y, 2) + case 31+3: + SQUARE_TWO_NEIGHBOR_QUADRANTS(1, 0, 0); + case 31+6: + SQUARE_TWO_NEIGHBOR_QUADRANTS(0, 1, 90); + case 31+12: + SQUARE_TWO_NEIGHBOR_QUADRANTS(-1, 0, 180); + case 31+9: + SQUARE_TWO_NEIGHBOR_QUADRANTS(0, -1, 270); +#undef SQUARE_TWO_NEIGHBOR_QUADRANTS + + case 31+5: + SQUARE_TWO_OPPOSING_QUADRANTS(1, 0, 0); + case 31+10: + SQUARE_TWO_OPPOSING_QUADRANTS(0, 1, 90); + +#define SQUARE_THREE_QUADRANTS(x, y, angle) \ + SQUARE_SINGLE_PIESLICE(x, y, 3) + case 31+7: + SQUARE_THREE_QUADRANTS(1, 0, 0); + case 31+14: + SQUARE_THREE_QUADRANTS(0, 1, 90); + case 31+13: + SQUARE_THREE_QUADRANTS(-1, 0, 180); + case 31+11: + SQUARE_THREE_QUADRANTS(0, -1, 270); +#undef SQUARE_THREE_QUADRANTS + +#define DIAMOND_SINGLE_QUADRANT(x, y, angle) \ + DIAMOND_SINGLE_PIESLICE(x, y, 1) + case 47+1: + DIAMOND_SINGLE_QUADRANT(1, 0, 0); + case 47+2: + DIAMOND_SINGLE_QUADRANT(0, 1, 90); + case 47+4: + DIAMOND_SINGLE_QUADRANT(-1, 0, 180); + case 47+8: + DIAMOND_SINGLE_QUADRANT(0, -1, 270); +#undef DIAMOND_SINGLE_QUADRANT + +#define DIAMOND_TWO_NEIGHBOR_QUADRANTS(x, y, angle) \ + DIAMOND_SINGLE_PIESLICE(x, y, 2) + case 47+3: + DIAMOND_TWO_NEIGHBOR_QUADRANTS(1, 0, 0); + case 47+6: + DIAMOND_TWO_NEIGHBOR_QUADRANTS(0, 1, 90); + case 47+12: + DIAMOND_TWO_NEIGHBOR_QUADRANTS(-1, 0, 180); + case 47+9: + DIAMOND_TWO_NEIGHBOR_QUADRANTS(0, -1, 270); +#undef DIAMOND_TWO_NEIGHBOR_QUADRANTS + + + case 47+5: + DIAMOND_TWO_OPPOSING_QUADRANTS(1, 0, 0); + case 47+10: + DIAMOND_TWO_OPPOSING_QUADRANTS(0, 1, 90); +#undef DIAMOND_TWO_OPPOSING_QUADRANTS +#undef SQUARE_TWO_OPPOSING_QUADRANTS + +#define DIAMOND_THREE_QUADRANTS(x, y, angle) \ + DIAMOND_SINGLE_PIESLICE(x, y, 3) + case 47+7: + DIAMOND_THREE_QUADRANTS(1, 0, 0); + case 47+14: + DIAMOND_THREE_QUADRANTS(0, 1, 90); + case 47+13: + DIAMOND_THREE_QUADRANTS(-1, 0, 180); + case 47+11: + DIAMOND_THREE_QUADRANTS(0, -1, 270); +#undef DIAMOND_THREE_QUADRANTS +#undef DIAMOND_SINGLE_PIESLICE +#undef SQUARE_SINGLE_PIESLICE + + default: + int_warn(NO_CARET, "PDF: unknown point type number %d", number); + } + } + + PDF_restore(myPDF); + PDF_xLast = x; + PDF_yLast = y; +} + + +TERM_PUBLIC int +PDF_justify_text (enum JUSTIFY mode) +{ + PDF_TextJust = mode; + return (TRUE); +} + + +TERM_PUBLIC int +PDF_text_angle (int ang) +{ + PDF_TextAngle = ang; + return (TRUE); +} + + +TERM_PUBLIC void +PDF_put_text (unsigned int x, unsigned int y, const char *str) +{ + char *alignment = NULL; + double h = x, v = y; + + PDF_PathClose (); + + /* horizontal justification*/ + switch (PDF_TextJust) { + case LEFT: + alignment = "left"; + break; + case CENTRE: + alignment = "center"; + break; + case RIGHT: + alignment = "right"; + break; + } + + if (PDF_TextAngle) { + PDF_save(myPDF); + PDF_translate(myPDF, h, v); + PDF_rotate(myPDF, PDF_TextAngle); + /* vertical justification*/ + PDF_translate(myPDF, 0, -(PDF_fontAscent-PDF_fontDescent)/2); + PDF_show_boxed(myPDF, str, 0,0, 0, 0, alignment, NULL); + PDF_restore(myPDF); + } else { + /* vertical justification*/ + v -= (PDF_fontAscent - PDF_fontDescent) / 2; + PDF_show_boxed(myPDF, str, h , v, 0, 0, alignment, NULL); + } + +} + + +TERM_PUBLIC int +PDF_set_font (const char *font) +{ + + if (!font || !(*font)) { + strcpy (PDF_fontNameCur, PDF_fontNameDef); + PDF_fontSizeCur = PDF_fontSizeDef; + } else { + int sep = strcspn(font,","); + if (sep > 0) { + strncpy(PDF_fontNameCur,font,sep); + PDF_fontNameCur[sep] = NUL; + } + if (font[sep] == ',') + sscanf(&(font[sep+1]), "%lf", &PDF_fontSizeCur); + } + + PDF_PathClose(); + PDF_SetFont(); + + term->h_char = PDF_fontAvWidth; + term->v_char = (PDF_fontAscent + PDF_fontDescent + PDF_fontLeading); + + return (TRUE); +} + +TERM_PUBLIC void +PDF_boxfill(int style, unsigned int x1, unsigned int y1, + unsigned int width, unsigned int height) +{ + gpiPoint corner[4]; + + corner[0].x = x1; corner[0].y = y1; + corner[1].x = x1+width; corner[1].y = y1; + corner[2].x = x1+width; corner[2].y = y1+height; + corner[3].x = x1; corner[3].y = y1+height; + + corner->style = style; + PDF_filled_polygon(4, corner); +} + +TERM_PUBLIC void +PDF_filled_polygon(int points, gpiPoint* corners) +{ + int i; + int fillpar = corners->style >> 4; + int style = corners->style &= 0xf; + + PDF_PathClose(); + PDF_save(myPDF); + + switch (style) { + case FS_EMPTY: /* fill with white */ + PDF_setgray(myPDF, 1); + break; + case FS_SOLID: + { + double fact = (double)fillpar * 0.01; + double _fact = (double)(100-fillpar) * 0.01; + double red = PDF_current_rgb.r * fact + _fact; + double green = PDF_current_rgb.g * fact + _fact; + double blue = PDF_current_rgb.b * fact + _fact; + if (PDF_monochrome) + PDF_setgray_fill(myPDF, PDF_current_gray); + else + PDF_setrgbcolor_fill(myPDF, red, green, blue); + } + break; +#if !HAVE_OLD_LIBPDF + case FS_PATTERN: + fillpar = fillpar % (PDF_patterns + 1) /* 0 == white */; + switch (fillpar) { + case 0: + /* fill with white */ + PDF_setcolor(myPDF, "fill", "rgb", 1, 1, 1, 0 /* unused */); + break; + default: + PDF_setcolor(myPDF, "fill", "pattern", PDF_patternHandles[fillpar - 1], 0, 0, 0); + } + break; +#endif + default: + break; + } + + PDF_moveto(myPDF, corners[0].x, corners[0].y); + for (i=1; itype == TC_LT) { + struct rgb *this_color = web_color_rgbs + 1 + PDF_Pen_RealID(colorspec->lt); + PDF_current_rgb.r = this_color->r / 255.0; + PDF_current_rgb.g = this_color->g / 255.0; + PDF_current_rgb.b = this_color->b / 255.0; + PDF_current_gray = 0.0; /* monochrome mode only */ + } else if (colorspec->type == TC_FRAC) { + rgb1maxcolors_from_gray( colorspec->value, &PDF_current_rgb); + PDF_current_gray = colorspec->value; /* monochrome mode only */ + } else if (colorspec->type == TC_RGB) { + PDF_current_rgb.r = (double)((colorspec->lt >> 16 ) & 255) / 255.; + PDF_current_rgb.g = (double)((colorspec->lt >> 8 ) & 255) / 255.; + PDF_current_rgb.b = (double)(colorspec->lt & 255) / 255.; + } else + return; + + /* make sure that the path is stroked with the current color + * before changing the color */ + PDF_PathClose(); + + if (PDF_monochrome && colorspec->type != TC_RGB) + PDF_setgray(myPDF, PDF_current_gray); /* FIXME - Should this be NTSC(current_rgb)? */ + else + PDF_setrgbcolor(myPDF, PDF_current_rgb.r, PDF_current_rgb.g, PDF_current_rgb.b); + + /* mark linetype invalid so that the color will be + * set when PDF_linetype() is called next */ + PDF_LineType = LT_UNDEFINED; +} + +TERM_PUBLIC void +PDF_previous_palette() +{ +} + +#ifdef WITH_IMAGE +TERM_PUBLIC void +PDF_image (unsigned M, unsigned N, coordval * image, gpiPoint * corner, t_imagecolor color_mode) +{ + unsigned char *pixel; + float xscale, yscale; + int i, im; + + /* Allocate memory to hold a copy of the entire image in raw RGB format */ + unsigned char *rawrgb = gp_alloc( M*N*3, "Raw RGB image"); + + /* Convert the input image into raw RGB 24-bit color representation */ + if (color_mode == IC_RGB) { + for (i=0, pixel=rawrgb; ienhanced_flush)(); + + /* I think we can only get here if *str == '}' */ + enh_err_check(str); + + if (!*++str) + break; /* end of string */ + + /* else carry on and process the rest of the string */ + } + + PDF_restore(myPDF); + + enhanced_max_height += enhanced_min_height; + + /* We can do text justification by running the entire top level string */ + /* through 2 times, with the ENHpdf_sizeonly flag set the first time. */ + /* After seeing where the final position is, we then offset the start */ + /* point accordingly and run it again. */ + if (PDF_TextJust == RIGHT || PDF_TextJust == CENTRE) { + int justification = PDF_TextJust; + int x_offset = PDF_xLast - x; + int y_offset = 0; + + if (PDF_TextAngle != 0) + y_offset = PDF_yLast - y; + PDF_TextJust = LEFT; + ENHpdf_sizeonly = FALSE; + + if (justification == RIGHT) { + ENHPDF_put_text(x - x_offset, y - y_offset, original_string); + } else if (justification == CENTRE) { + ENHPDF_put_text(x - x_offset/2, y - y_offset/2, original_string); + } + PDF_TextJust = justification; + } + +} + +#endif /* TERM_BODY */ + +#ifdef TERM_TABLE +TERM_TABLE_START (pdf_driver) + "pdf", "PDF (Portable Document File) file driver", + 0 /* xmax */ , 0 /* ymax */ , 0 /* vchar */ , 0 /* hchar */ , + 0 /* vtic */ , 0 /* htic */ , + PDF_options, PDF_init, PDF_reset, PDF_text, null_scale, PDF_graphics, + PDF_move, PDF_vector, PDF_linetype, PDF_put_text, PDF_text_angle, + PDF_justify_text, PDF_point, do_arrow, PDF_set_font, do_pointsize, + TERM_BINARY, + 0 /* suspend */, 0 /* resume */ , PDF_boxfill, PDF_linewidth +# ifdef USE_MOUSE + , 0, 0, 0, 0, 0 /* no mouse support for pdf */ +# endif + , PDF_make_palette, + PDF_previous_palette, + PDF_set_color, + PDF_filled_polygon +#ifdef WITH_IMAGE + , PDF_image +#endif + , ENHPDF_OPEN, ENHPDF_FLUSH, do_enh_writec +TERM_TABLE_END (pdf_driver) +#undef LAST_TERM +#define LAST_TERM pdf_driver +#endif /* TERM_TABLE */ + +#endif /* TERM_PROTO_ONLY */ + +#ifdef TERM_HELP +START_HELP(pdf) +"1 pdf", +"?commands set terminal pdf", +"?set terminal pdf", +"?set term pdf", +"?terminal pdf", +"?term pdf", +"?pdf", +" This terminal produces files in the Adobe Portable Document Format", +" (PDF), useable for printing or display with tools like Acrobat Reader", +"", +" Syntax:", +" set terminal pdf {monochrome|color|colour}", +" {{no}enhanced}", +" {fname \"\"} {fsize }", +" {font \"{,}\"}", +" {linewidth } {rounded|butt}", +" {solid|dashed} {dl }}", +" {size {unit},{unit}}", +"", +" The default is to use a different color for each line type. Selecting", +" `monochome` will use black for all linetypes, in which case you probably", +" want to select `dashed` to distinguish line types. Even in in mono mode", +" you can still use explicit colors for filled areas or linestyles.", +"", +" where is the name of the default font to use (default Helvetica)", +" and is the font size (in points, default 12).", +" For help on which fonts are available or how to install new ones, please", +" see the documentation for your local installation of pdflib.", +"", +" The `enhanced` option enables enhanced text processing features", +" (subscripts, superscripts and mixed fonts). See `enhanced`.", +"", +" The width of all lines in the plot can be increased by the factor ", +" specified in `linewidth`. Similarly `dashlength` is a multiplier for the", +" default dash spacing.", +"", +" `rounded` sets line caps and line joins to be rounded; `butt` is the", +" default, butt caps and mitered joins.", +"", +" The default size for PDF output is 5 inches by 3 inches. The `size` option", +" changes this to whatever the user requests. By default the X and Y sizes", +" are taken to be in inches, but other units are possible (currently only cm).", +"" +END_HELP(pdf) +#endif