/* Hello, Emacs, this is -*-C-*- * $Id: pslatex.trm,v 1.69.2.3 2009/05/11 21:47:30 sfeam Exp $ */ /* GNUPLOT - pslatex.trm */ /*[ * Copyright 1990 - 1993, 1998, 2004 * * Permission to use, copy, and distribute this software and its * documentation for any purpose with or without fee is hereby granted, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. * * Permission to modify the software is granted, but not the right to * distribute the complete modified source code. Modifications are to * be distributed as patches to the released version. Permission to * distribute binaries produced by compiling modified sources is granted, * provided you * 1. distribute the corresponding source modifications from the * released version in the form of a patch file along with the binaries, * 2. add special version identification to distinguish your version * in addition to the base release version number, * 3. provide your name and address as the primary contact for the * support of your modified version, and * 4. retain our contact information in regard to use of the base * software. * Permission to distribute the released version of the source code along * with corresponding source modifications in the form of a patch file is * granted with same provisions 2 through 4 for binary distributions. * * This software is provided "as is" without express or implied warranty * to the extent permitted by applicable law. ]*/ /* * This file is included by ../term.c. * * This file supplies the terminal drivers: * pslatex -- LaTeX with embedded postscript * pstex -- plain TeX with embedded postscript * epslatex -- LaTeX using \includegraphics, postscript part in an * external file * * AUTHORS * George Phillips * Russell Lang * David Kotz * * Petr Mikulik, May 2000: terminal entries for PM3D functionality * * Dan Sebald, 5 March 2003: terminal entry for image functionality * * Theo Hopman * 23 May 2003: * - added epslatex support. Replaces epslatex.trm; pointtype * and linetypes for epslatex terminal are now identical to * those of pslatex terminal. * - added arbitrary text rotations to all [e]ps[la]tex * terminals. * 27 May 2004: * - epslatex patch updated for gnuplot 4.0 * * Harald Harders (h.harders@tu-bs.de), 2005-02-08: * - Merged functionality of postscript, pslatex, pstex, and * epslatex terminals. Therefore deleted epslatex.trm. * - Added a standalone mode to the epslatex mode for standalone use without * an additional LaTeX document. * - Fixed text rotation of ps(la)tex terminals. * * Send your comments or suggestions to (gnuplot-info@lists.sourceforge.net). */ #include "driver.h" #ifdef TERM_REGISTER register_term(pslatex) register_term(pstex) register_term(epslatex) #endif #ifdef TERM_PROTO /* Common functions for epslatex and ps(la)tex */ /* All these routines begin with PSLATEX_ */ TERM_PUBLIC void PSLATEX_reset __PROTO((void)); /* Functions for ps(la)tex */ /* All these routines begin with PSTEX_ */ TERM_PUBLIC void PSTEX_reopen_output __PROTO((void)); TERM_PUBLIC void PSTEX_common_init __PROTO((void)); TERM_PUBLIC void PSTEX_put_text __PROTO((unsigned int x, unsigned int y, const char *str)); TERM_PUBLIC void PSTEX_text __PROTO((void)); /* Functions for epslatex */ /* All these routines begin with EPSLATEX_ */ TERM_PUBLIC void EPSLATEX_reopen_output __PROTO((void)); TERM_PUBLIC void EPSLATEX_common_init __PROTO((void)); TERM_PUBLIC void EPSLATEX_put_text __PROTO((unsigned int x, unsigned int y, const char *str)); TERM_PUBLIC void EPSLATEX_linetype __PROTO((int linetype)); TERM_PUBLIC void EPSLATEX_layer __PROTO((t_termlayer syncpoint)); /* additional LaTeX header information for epslatex terminal */ TERM_PUBLIC char *epslatex_header = NULL; #endif /* TERM_PROTO */ #ifndef TERM_PROTO_ONLY #ifdef TERM_BODY #include "post.h" struct pstex_text_command { int x, y, angle, justify; char *label; struct pstex_text_command *next; }; static struct pstex_text_command *pstex_labels = NULL; static int epslatex_text_layer = 0; /* Support for optimization of set_color */ static t_colorspec tex_previous_colorspec = {-1, 0, 0.0}; /* Initialize to invalid type */ static char tex_current_color[64]; static TBOOLEAN tex_color_synced = FALSE; #define EPSLATEX_sync_color \ do { \ if (!tex_color_synced) { \ fputs(tex_current_color,gpoutfile); \ tex_color_synced = TRUE; \ } \ } while (0) /* Common functions for epslatex and ps(la)tex */ TERM_PUBLIC void PSLATEX_reset() { switch (ps_params->terminal) { case PSTERM_EPSLATEX: PS_reset(); if (gpoutfile) { fprintf(gpoutfile, "\ \\gplbacktext\n\ \\put(0,0){\\includegraphics{%s}}%%\n\ \\gplfronttext\n\ \\end{picture}%%\n\ \\endgroup\n", pslatex_auxname); if (ps_params->epslatex_standalone) fputs("\\end{document}\n", gpoutfile); } break; case PSTERM_PSLATEX: fputs("\ \\end{picture}%\n\ \\endgroup\n\ \\endinput\n", gpoutfile); break; case PSTERM_PSTEX: fputs("\ \\endGNUPLOTpicture\n\ \\endgroup\n\ \\endinput\n", gpoutfile); break; default:; /* do nothing, just avoid a compiler warning */ } if (pslatex_auxname) { free(pslatex_auxname); pslatex_auxname = NULL; } if (gppsfile && (gppsfile != gpoutfile)) { fclose(gppsfile); gppsfile = NULL; } } /* Functions for ps(la)tex */ TERM_PUBLIC void PSTEX_reopen_output() { if (outstr) { char *dotIndex; /* if there's no extension, append ".ps" */ if ((dotIndex = strrchr(outstr, '.')) == NULL) dotIndex = strchr(outstr, NUL); /* try to open the auxiliary file for the postscript parts. */ if (ps_params->useauxfile) { /* length of outstr plus ('.' or '\0') plus "eps" plus '\0' */ pslatex_auxname = gp_realloc(pslatex_auxname,dotIndex - outstr + 5, "pslatex aux filename"); if (pslatex_auxname) { /* include period or '\0' */ strncpy(pslatex_auxname, outstr, (dotIndex - outstr) + 1); /* period or '\0' is overwritten with period, and "ps" appended */ strcpy(pslatex_auxname + (dotIndex - outstr), ".ps"); gppsfile = fopen(pslatex_auxname, "w"); if (gppsfile == (FILE *) NULL) { fprintf(stderr, "Cannot open aux file %s for output. Switching off auxfile option.\n", pslatex_auxname); free(pslatex_auxname); pslatex_auxname = NULL; ps_params->useauxfile = FALSE; gppsfile = gpoutfile; } } else { fprintf(stderr, "Cannot make PostScript file name from %s\n", outstr); fprintf(stderr, "Turning off auxfile option\n"); ps_params->useauxfile = FALSE; gppsfile = gpoutfile; } } else gppsfile = gpoutfile; } else { if (ps_params->useauxfile) { fprintf(stderr, "Cannot use aux file on stdout. Switching off auxfile option.\n"); ps_params->useauxfile = FALSE; } gppsfile = gpoutfile; } } TERM_PUBLIC void PSTEX_common_init() { switch (ps_params->terminal) { case PSTERM_PSLATEX: fprintf(gpoutfile,"\ %% GNUPLOT: LaTeX picture with Postscript\n\ \\begingroup%%\n\ \\makeatletter%%\n\ \\newcommand{\\GNUPLOTspecial}{%%\n\ \\@sanitize\\catcode`\\%%=14\\relax\\special}%%\n\ \\setlength{\\unitlength}{%.4fbp}%%\n", 1.0 / (2*PS_SC)); fprintf(gpoutfile, "\\begin{picture}(%d,%d)(0,0)%%\n", (int) (xsize * term->xmax), (int) (ysize * term->ymax)); break; case PSTERM_PSTEX: /* write plain TeX header */ fprintf(gpoutfile, "\ %% GNUPLOT: plain TeX with Postscript\n\ \\begingroup\n\ \\catcode`\\@=11\\relax\n\ \\def\\GNUPLOTspecial{%%\n\ \\def\\do##1{\\catcode`##1=12\\relax}\\dospecials\n\ \\catcode`\\{=1\\catcode`\\}=2\\catcode\\%%=14\\relax\\special}%%\n\ %%\n\ \\expandafter\\ifx\\csname GNUPLOTpicture\\endcsname\\relax\n\ \\csname newdimen\\endcsname\\GNUPLOTunit\n\ \\gdef\\GNUPLOTpicture(#1,#2){\\vbox to#2\\GNUPLOTunit\\bgroup\n\ \\def\\put(##1,##2)##3{\\unskip\\raise##2\\GNUPLOTunit\n\ \\hbox to0pt{\\kern##1\\GNUPLOTunit ##3\\hss}\\ignorespaces}%%\n\ \\def\\ljust##1{\\vbox to0pt{\\vss\\hbox to0pt{##1\\hss}\\vss}}%%\n\ \\def\\cjust##1{\\vbox to0pt{\\vss\\hbox to0pt{\\hss ##1\\hss}\\vss}}%%\n\ \\def\\rjust##1{\\vbox to0pt{\\vss\\hbox to0pt{\\hss ##1}\\vss}}%%\n\ \\def\\stack##1{\\let\\\\=\\cr\\tabskip=0pt\\halign{\\hfil ####\\hfil\\cr ##1\\crcr}}%%\n\ \\def\\lstack##1{\\hbox to0pt{\\vbox to0pt{\\vss\\stack{##1}}\\hss}}%%\n\ \\def\\cstack##1{\\hbox to0pt{\\hss\\vbox to0pt{\\vss\\stack{##1}}\\hss}}%%\n\ \\def\\rstack##1{\\hbox to0pt{\\vbox to0pt{\\stack{##1}\\vss}\\hss}}%%\n\ \\vss\\hbox to#1\\GNUPLOTunit\\bgroup\\ignorespaces}%%\n\ \\gdef\\endGNUPLOTpicture{\\hss\\egroup\\egroup}%%\n\ \\fi\n\ \\GNUPLOTunit=%.4fbp\n", 1.0 / (2*PS_SC)); fprintf(gpoutfile, "\\GNUPLOTpicture(%d,%d)\n", (int) (xsize * term->xmax), (int) (ysize * term->ymax)); break; default:; /* do nothing, just avoid a compiler warning */ } if (gppsfile != gpoutfile) { /* these are taken from the post.trm file computation * of the bounding box, but without the X_OFF and Y_OFF */ int urx = (int) (xsize * term->xmax / (2*PS_SC) + 0.5); int ury = (int) (ysize * term->ymax / (2*PS_SC) + 0.5); /* moved this code here from beginning of the function * pslatex_auxname is only != NULL with the `auxfile' option */ char *psfile_basename = strrchr(pslatex_auxname, DIRSEP1); /* If pslatex_auxname is not a simple file name, but a path, * we need to strip the path off the auxiliary file name, * because tex file and ps aux file end up in the same directory! */ if (psfile_basename) psfile_basename++; else { #if DIRSEP2 != NUL psfile_basename = strrchr(pslatex_auxname, DIRSEP2); if (psfile_basename) psfile_basename++; else psfile_basename = pslatex_auxname; #else psfile_basename = pslatex_auxname; #endif } /* generate special which xdvi and dvips can handle */ fprintf(gpoutfile, " \\special{psfile=%s llx=0 lly=0 urx=%d ury=%d rwi=%d}\n", psfile_basename, urx, ury, 10 * urx); } else fputs(" {\\GNUPLOTspecial{\"\n", gpoutfile); /* HH: really necessary? ps_ang = 0; ps_justify = 0; */ pstex_labels = (struct pstex_text_command *) NULL; } TERM_PUBLIC void PSTEX_put_text(unsigned int x, unsigned int y, const char *str) { struct pstex_text_command *tc; /* ignore empty strings */ if (str[0] == NUL) return; /* Save the text for later printing after the core graphics */ tc = (struct pstex_text_command *) gp_alloc(sizeof(struct pstex_text_command), term->name); tc->x = x; tc->y = y; tc->label = (char *) gp_alloc(strlen(str) + 1, term->name); strcpy(tc->label, str); tc->justify = ps_justify; tc->angle = ps_ang; tc->next = pstex_labels; pstex_labels = tc; } TERM_PUBLIC void PSTEX_text() { struct pstex_text_command *tc; PS_text(); if (gppsfile == gpoutfile) fputs(" }}%\n", gpoutfile); if (ps_params->fontsize) { if (ps_params->terminal == PSTERM_PSLATEX) fprintf(gpoutfile, "\\fontsize{%g}{\\baselineskip}\\selectfont\n", ps_params->fontsize); /* Should have an else clause here to handle pstex equivalent */ } for (tc = pstex_labels; tc != (struct pstex_text_command *) NULL; tc = tc->next) { fprintf(gpoutfile, " \\put(%d,%d){", tc->x, tc->y); if ((ps_params->rotate) && (tc->angle != 0)) fprintf(gpoutfile, "\ %%\n \\special{ps: gsave currentpoint currentpoint translate\n\ %d rotate neg exch neg exch translate}%%\n ", 360 - tc->angle); if ((ps_params->terminal == PSTERM_PSLATEX) && ((tc->label[0] == '{') || (tc->label[0] == '['))) { fprintf(gpoutfile, "\\makebox(0,0)%s", tc->label); } else switch (tc->justify) { case LEFT: fprintf(gpoutfile, (ps_params->terminal == PSTERM_PSLATEX ? "\\makebox(0,0)[l]{\\strut{}%s}" : "\\ljust{\\strut{}%s}"), tc->label); break; case CENTRE: fprintf(gpoutfile, (ps_params->terminal == PSTERM_PSLATEX ? "\\makebox(0,0){\\strut{}%s}" : "\\cjust{\\strut{}%s}"), tc->label); break; case RIGHT: fprintf(gpoutfile, (ps_params->terminal == PSTERM_PSLATEX ? "\\makebox(0,0)[r]{\\strut{}%s}" : "\\rjust{\\strut{}%s}"), tc->label); break; } if ((ps_params->rotate) && (tc->angle != 0)) fputs("%\n \\special{ps: currentpoint grestore moveto}%\n ", gpoutfile); fputs("}%\n", gpoutfile); } while (pstex_labels) { tc = pstex_labels->next; free(pstex_labels->label); free(pstex_labels); pstex_labels = tc; } } /* Functions for epslatex */ /* the common init function for the epslatex driver */ TERM_PUBLIC void EPSLATEX_common_init() { char *fontfamily = NULL; char *fontseries = NULL; char *fontshape = NULL; if (!gpoutfile) { char *temp = gp_alloc(strlen(outstr) + 1, "temp file string"); if (temp) { strcpy(temp, outstr); term_set_output(temp); /* will free outstr */ if (temp != outstr) { if (temp) free(temp); temp = outstr; } } else os_error(c_token, "Cannot reopen output files"); } if (!outstr) os_error(c_token, "epslatex terminal cannot write to standard output"); if (gpoutfile) { char *inputenc = NULL; fprintf(gpoutfile, "%% GNUPLOT: LaTeX picture with Postscript\n"); switch(encoding) { case S_ENC_DEFAULT: break; case S_ENC_ISO8859_1: inputenc = "latin1"; break; case S_ENC_ISO8859_2: inputenc = "latin2"; break; case S_ENC_ISO8859_15: inputenc = "latin9"; break; case S_ENC_CP437: inputenc = "cp437de"; break; case S_ENC_CP850: inputenc = "cp850"; break; case S_ENC_CP852: inputenc = "cp852"; break; case S_ENC_CP1250: inputenc = "cp1250"; break; case S_ENC_KOI8_R: inputenc = "koi8-r"; break; case S_ENC_KOI8_U: inputenc = "koi8-u"; break; case S_ENC_INVALID: int_error(NO_CARET, "invalid input encoding used"); break; default: /* do nothing */ break; } /* Clear previous state */ tex_previous_colorspec.type = -1; /* Clear any leftover text-layering state */ EPSLATEX_layer(TERM_LAYER_RESET); /* Analyse LaTeX font name 'family,series,shape' */ if ((strlen(ps_params->font) > 0) && (strcmp(ps_params->font,"default") != 0)) { char *comma = NULL; fontfamily = gp_alloc(strlen(ps_params->font)+1, "EPSLATEX_common_init"); fontseries = gp_alloc(strlen(ps_params->font)+1, "EPSLATEX_common_init"); fontshape = gp_alloc(strlen(ps_params->font)+1, "EPSLATEX_common_init"); strcpy(fontfamily,ps_params->font); *fontseries = '\0'; *fontshape = '\0'; if ((comma = strchr(fontfamily, ',')) != NULL) { *comma = '\0'; strcpy(fontseries,comma+1); if ((comma = strchr(fontseries, ',')) != NULL) { *comma = '\0'; strcpy(fontshape,comma+1); } } } if (ps_params->epslatex_standalone) { fprintf(gpoutfile, "\ \\documentclass{minimal}\n\ %% Set font size\n\ \\makeatletter\n\ \\def\\@ptsize{%d}\n\ \\InputIfFileExists{size%d.clo}{}{%%\n\ \\GenericError{(gnuplot) \\space\\space\\space\\@spaces}{%%\n\ Gnuplot Error: File `size%d.clo' not found! Could not set font size%%\n\ }{See the gnuplot documentation for explanation.%%\n\ }{For using a font size a file `size.clo' has to exist.\n\ Falling back ^^Jto default fontsize 10pt.}%%\n\ \\def\\@ptsize{0}\n\ \\input{size10.clo}%%\n\ }%%\n\ \\makeatother\n", (int)(ps_params->fontsize-10), (int)(ps_params->fontsize), (int)(ps_params->fontsize)); if (fontfamily && strlen(fontfamily) > 0) fprintf(gpoutfile, "\\renewcommand*\\rmdefault{%s}%%\n", fontfamily); if (fontseries && strlen(fontseries) > 0) fprintf(gpoutfile, "\\renewcommand*\\mddefault{%s}%%\n", fontseries); if (fontshape && strlen(fontshape) > 0) fprintf(gpoutfile, "\\renewcommand*\\updefault{%s}%%\n", fontshape); fputs("\ % Load packages\n\ \\usepackage{graphicx}\n\ \\usepackage{color}\n", gpoutfile); if (inputenc) fprintf(gpoutfile, "\\usepackage[%s]{inputenc}\n", inputenc); fprintf(gpoutfile, "\ \\makeatletter\n\ %% Select an appropriate default driver (from TeXLive graphics.cfg)\n\ \\begingroup\n\ \\chardef\\x=0 %%\n\ %% check pdfTeX\n\ \\@ifundefined{pdfoutput}{}{%%\n\ \\ifcase\\pdfoutput\n\ \\else\n\ \\chardef\\x=1 %%\n\ \\fi\n\ }%%\n\ %% check VTeX\n\ \\@ifundefined{OpMode}{}{%%\n\ \\chardef\\x=2 %%\n\ }%%\n\ \\expandafter\\endgroup\n\ \\ifcase\\x\n\ %% default case\n\ \\PassOptionsToPackage{dvips}{geometry}\n\ \\or\n\ %% pdfTeX is running in pdf mode\n\ \\PassOptionsToPackage{pdftex}{geometry}\n\ \\else\n\ %% VTeX is running\n\ \\PassOptionsToPackage{vtex}{geometry}\n\ \\fi\n\ \\makeatother\n\ %% Set papersize\n\ \\usepackage[papersize={%.2fbp,%.2fbp},text={%.2fbp,%.2fbp}]{geometry}\n\ %% No page numbers and no paragraph indentation\n\ \\pagestyle{empty}\n\ \\setlength{\\parindent}{0bp}%%\n\ %% Load configuration file\n\ \\InputIfFileExists{gnuplot.cfg}{%%\n\ \\typeout{Using configuration file gnuplot.cfg}%%\n\ }{%%\n\ \\typeout{No configuration file gnuplot.cfg found.}%%\n\ }%%\n\ %s\n\ \\begin{document}\n", term->xmax * xsize / (2.0*PS_SC), term->ymax * ysize / (2.0*PS_SC), term->xmax * xsize / (2.0*PS_SC), term->ymax * ysize / (2.0*PS_SC), epslatex_header ? epslatex_header : "%" ); } fputs("\\begingroup\n", gpoutfile); if (inputenc) fprintf(gpoutfile, "\ %% Encoding inside the plot. In the header of your document, this encoding\n\ %% should to defined, e.g., by using\n\ %% \\usepackage[%s,]{inputenc}\n\ \\inputencoding{%s}%%\n", inputenc, inputenc); if (!ps_params->epslatex_standalone) { if (fontfamily && strlen(fontfamily) > 0) fprintf(gpoutfile, " \\fontfamily{%s}%%\n", fontfamily); if (fontseries && strlen(fontseries) > 0) fprintf(gpoutfile, " \\fontseries{%s}%%\n", fontseries); if (fontshape && strlen(fontshape) > 0) fprintf(gpoutfile, " \\fontshape{%s}%%\n", fontshape); if (fontfamily || fontseries || fontshape) fputs(" \\selectfont\n", gpoutfile); if (epslatex_header) fprintf(gpoutfile, "%s\n", epslatex_header ); } fprintf(gpoutfile, "\ \\makeatletter\n\ \\providecommand\\color[2][]{%%\n\ \\GenericError{(gnuplot) \\space\\space\\space\\@spaces}{%%\n\ Package color not loaded in conjunction with\n\ terminal option `colourtext'%%\n\ }{See the gnuplot documentation for explanation.%%\n\ }{Either use 'blacktext' in gnuplot or load the package\n\ color.sty in LaTeX.}%%\n\ \\renewcommand\\color[2][]{}%%\n\ }%%\n\ \\providecommand\\includegraphics[2][]{%%\n\ \\GenericError{(gnuplot) \\space\\space\\space\\@spaces}{%%\n\ Package graphicx or graphics not loaded%%\n\ }{See the gnuplot documentation for explanation.%%\n\ }{The gnuplot epslatex terminal needs graphicx.sty or graphics.sty.}%%\n\ \\renewcommand\\includegraphics[2][]{}%%\n\ }%%\n\ \\providecommand\\rotatebox[2]{#2}%%\n\ \\@ifundefined{ifGPcolor}{%%\n\ \\newif\\ifGPcolor\n\ \\GPcolor%s\n\ }{}%%\n\ \\@ifundefined{ifGPblacktext}{%%\n\ \\newif\\ifGPblacktext\n\ \\GPblacktext%s\n\ }{}%%\n\ %% define a \\g@addto@macro without @ in the name:\n\ \\let\\gplgaddtomacro\\g@addto@macro\n\ %% define empty templates for all commands taking text:\n\ \\gdef\\gplbacktext{}%%\n\ \\gdef\\gplfronttext{}%%\n\ \\makeatother\n", (ps_params->color?"true":"false"), (ps_params->blacktext?"true":"false") ); /* use \expandafter\def\csname LT0\endcsname{...} * instead of \def\LT0{...} because digits may not be part of * \... sequences */ fputs("\ \\ifGPblacktext\n\ % no textcolor at all\n\ \\def\\colorrgb#1{}%\n\ \\def\\colorgray#1{}%\n\ \\else\n\ % gray or color?\n\ \\ifGPcolor\n\ \\def\\colorrgb#1{\\color[rgb]{#1}}%\n\ \\def\\colorgray#1{\\color[gray]{#1}}%\n\ \\expandafter\\def\\csname LTw\\endcsname{\\color{white}}%\n\ \\expandafter\\def\\csname LTb\\endcsname{\\color{black}}%\n\ \\expandafter\\def\\csname LTa\\endcsname{\\color{black}}%\n", gpoutfile); if (ps_params->oldstyle) { fputs("\ \\expandafter\\def\\csname LT0\\endcsname{\\color[rgb]{1,0,0}}%\n\ \\expandafter\\def\\csname LT1\\endcsname{\\color[rgb]{0,0,1}}%\n\ \\expandafter\\def\\csname LT2\\endcsname{\\color[rgb]{0,1,1}}%\n\ \\expandafter\\def\\csname LT3\\endcsname{\\color[rgb]{1,0,1}}%\n", gpoutfile); } else { fputs("\ \\expandafter\\def\\csname LT0\\endcsname{\\color[rgb]{1,0,0}}%\n\ \\expandafter\\def\\csname LT1\\endcsname{\\color[rgb]{0,1,0}}%\n\ \\expandafter\\def\\csname LT2\\endcsname{\\color[rgb]{0,0,1}}%\n\ \\expandafter\\def\\csname LT3\\endcsname{\\color[rgb]{1,0,1}}%\n\ \\expandafter\\def\\csname LT4\\endcsname{\\color[rgb]{0,1,1}}%\n\ \\expandafter\\def\\csname LT5\\endcsname{\\color[rgb]{1,1,0}}%\n\ \\expandafter\\def\\csname LT6\\endcsname{\\color[rgb]{0,0,0}}%\n\ \\expandafter\\def\\csname LT7\\endcsname{\\color[rgb]{1,0.3,0}}%\n\ \\expandafter\\def\\csname LT8\\endcsname{\\color[rgb]{0.5,0.5,0.5}}%\n", gpoutfile); } fputs("\ \\else\n\ % gray\n\ \\def\\colorrgb#1{\\color{black}}%\n\ \\def\\colorgray#1{\\color[gray]{#1}}%\n\ \\expandafter\\def\\csname LTw\\endcsname{\\color{white}}%\n\ \\expandafter\\def\\csname LTb\\endcsname{\\color{black}}%\n\ \\expandafter\\def\\csname LTa\\endcsname{\\color{black}}%\n\ \\expandafter\\def\\csname LT0\\endcsname{\\color{black}}%\n\ \\expandafter\\def\\csname LT1\\endcsname{\\color{black}}%\n\ \\expandafter\\def\\csname LT2\\endcsname{\\color{black}}%\n\ \\expandafter\\def\\csname LT3\\endcsname{\\color{black}}%\n\ \\expandafter\\def\\csname LT4\\endcsname{\\color{black}}%\n\ \\expandafter\\def\\csname LT5\\endcsname{\\color{black}}%\n\ \\expandafter\\def\\csname LT6\\endcsname{\\color{black}}%\n\ \\expandafter\\def\\csname LT7\\endcsname{\\color{black}}%\n\ \\expandafter\\def\\csname LT8\\endcsname{\\color{black}}%\n\ \\fi\n\ \\fi\n", gpoutfile); fprintf(gpoutfile,"\ \\setlength{\\unitlength}{%.4fbp}%%\n\ \\begin{picture}(%.2f,%.2f)%%\n", 1.0 / (2*PS_SC), term->xmax * xsize, term->ymax * ysize); } if (fontfamily) free(fontfamily); if (fontseries) free(fontseries); if (fontshape) free(fontshape); } TERM_PUBLIC void EPSLATEX_put_text(unsigned int x, unsigned int y, const char *str) { if (gpoutfile) { EPSLATEX_sync_color; fprintf(gpoutfile, " \\put(%d,%d){", x, y); if (ps_ang) fprintf(gpoutfile,"\\rotatebox{%d}{", ps_ang); if (((str[0] == '{') || (str[0] == '['))) { fprintf(gpoutfile, "\\makebox(0,0)%s", str); } else switch (ps_justify) { case LEFT: fprintf(gpoutfile, "\\makebox(0,0)[l]{\\strut{}%s}", str); break; case CENTRE: fprintf(gpoutfile, "\\makebox(0,0){\\strut{}%s}", str); break; case RIGHT: fprintf(gpoutfile, "\\makebox(0,0)[r]{\\strut{}%s}", str); break; } if (ps_ang) { fputs("}", gpoutfile); } fputs("}%\n", gpoutfile); } } /* assigns dest to outstr, so it must be allocated or NULL * and it must not be outstr itself ! */ void EPSLATEX_reopen_output() { char *psoutstr = NULL; if (outstr) { unsigned int outstrlen = strlen(outstr); if (strrchr(outstr, '.') != &outstr[outstrlen-4] ) { int_error(NO_CARET, "epslatex outputfile may not have dots inside %s", "their filenames before the extension .tex or .eps"); } /* copy filename to postsript output */ psoutstr = gp_alloc(outstrlen+5, "epslatex eps filename"); strcpy( psoutstr, outstr); if ((!strncmp( &outstr[outstrlen-4], ".eps", 4 )) || (!strncmp( &outstr[outstrlen-4], ".EPS", 4 ))) { if (ps_params->epslatex_standalone) int_error(NO_CARET, "For epslatex standalone mode, you have to %s", "give the tex filename as output"); /* rename primary output (tex) */ strncpy( &outstr[outstrlen-4], ".tex", 4); /* redirect FILE stream */ gppsfile = gpoutfile; gpoutfile = fopen(outstr,"w"); int_warn(NO_CARET, "Resetting primary output file to %s,\n\ PostScript output to %s", outstr, psoutstr); if (!gpoutfile) int_error(NO_CARET, "--- reopen failed"); } else { if (ps_params->epslatex_standalone) strncpy( &psoutstr[outstrlen-4], "-inc.eps", 9); else strncpy( &psoutstr[outstrlen-4], ".eps", 4); gppsfile = fopen(psoutstr,"w"); } if (!gppsfile) int_error(NO_CARET, "open of postscipt output file %s failed", psoutstr); /* set the name for the \includegraphics command */ pslatex_auxname = gp_alloc(strlen(psoutstr)-3, "epslatex TeX filename"); strncpy( pslatex_auxname, psoutstr, strlen(psoutstr)-4 ); pslatex_auxname[strlen(psoutstr)-4] = '\0'; free(psoutstr); } } TERM_PUBLIC void EPSLATEX_set_color(t_colorspec *colorspec) { double gray; /* EAM Jul 2006 - Filter out duplicate requests */ if (!memcmp(&tex_previous_colorspec, colorspec, sizeof(t_colorspec))) return; else memcpy(&tex_previous_colorspec, colorspec, sizeof(t_colorspec)); /* Fancy footwork to deal with mono/grayscale plots */ if (colorspec->type == TC_LT && !ps_params->color) PS_linetype(colorspec->lt); else PS_set_color(colorspec); /* Many [most? all?] of the set_color commands only affect the *.eps */ /* output stream. So rather than printing them all to the *.tex stream, */ /* we update the current color and set a flag to say it has changed. */ /* Only when some TeX object is output do we sync the current color by */ /* writing it out. */ tex_color_synced = FALSE; if (colorspec->type == TC_RGB) { double r = (double)((colorspec->lt >> 16 ) & 255) / 255.; double g = (double)((colorspec->lt >> 8 ) & 255) / 255.; double b = (double)(colorspec->lt & 255) / 255.; sprintf(tex_current_color, " \\colorrgb{%3.2f,%3.2f,%3.2f}%%\n",r,g,b); } if (colorspec->type == TC_LT) { int linetype = colorspec->lt; if (ps_params->oldstyle) linetype = (linetype % 4) + 3; else linetype = (linetype % 9) + 3; sprintf(tex_current_color, " \\csname LT%c\\endcsname%%\n", "wba012345678"[linetype]); } if (colorspec->type != TC_FRAC) return; /* map [0;1] to gray/colors */ gray = colorspec->value; if (ps_params->blacktext) { if (gray <= 0) sprintf(tex_current_color, " \\color{black}%%\n"); else if (gray >= 1) sprintf(tex_current_color, " \\color{white}%%\n"); else sprintf(tex_current_color, " \\colorgray{%s}%%\n",save_space(gray)); } else { rgb_color color; rgb1_from_gray( colorspec->value, &color ); sprintf(tex_current_color, " \\colorrgb{%3.2f,%3.2f,%3.2f}%%\n",color.r,color.g,color.b); } } TERM_PUBLIC void EPSLATEX_linetype(int linetype) { t_colorspec tempcol = {TC_LT, 0, 0.0}; tempcol.lt = linetype; PS_linetype(linetype); /* This leads to redundant *.eps output */ EPSLATEX_set_color(&tempcol); } /* * The TERM_LAYER mechanism is used here to signal a difference between * "front" text and "back" text. */ TERM_PUBLIC void EPSLATEX_layer(t_termlayer syncpoint) { switch (syncpoint) { case TERM_LAYER_RESET: /* Start of plot; reset flag */ epslatex_text_layer = 0; break; case TERM_LAYER_BACKTEXT: /* Start of "back" text layer */ if (epslatex_text_layer == 1) break; if (epslatex_text_layer == 2) fputs(" }%\n", gpoutfile); epslatex_text_layer = 1; fputs(" \\gplgaddtomacro\\gplbacktext{%\n", gpoutfile); break; case TERM_LAYER_FRONTTEXT:/* Start of "front" text layer */ if (epslatex_text_layer == 2) break; if (epslatex_text_layer == 1) fputs(" }%\n", gpoutfile); epslatex_text_layer = 2; fputs(" \\gplgaddtomacro\\gplfronttext{%\n", gpoutfile); break; case TERM_LAYER_END_TEXT: /* Close off front or back macro before leaving */ if (epslatex_text_layer == 1 || epslatex_text_layer == 2) fputs(" }%\n", gpoutfile); epslatex_text_layer = 0; break; default: break; } } #endif /* TERM_BODY */ #ifdef TERM_TABLE #ifndef GOT_POST_PROTO #define TERM_PROTO_ONLY #include "post.trm" #undef TERM_PROTO_ONLY #endif /* GOT_POST_PROTO */ TERM_TABLE_START(epslatex_driver) "epslatex", "LaTeX picture environment using graphicx package", PS_XMAX, PS_YMAX, EPSLATEX_VCHAR, EPSLATEX_HCHAR, PS_VTIC, PS_HTIC, PS_options, PS_init, PSLATEX_reset, PS_text, null_scale, PS_graphics, PS_move, PS_vector, EPSLATEX_linetype, EPSLATEX_put_text, PS_text_angle, PS_justify_text, PS_point, do_arrow, PS_set_font, PS_pointsize, TERM_BINARY|TERM_IS_POSTSCRIPT|TERM_CAN_CLIP /*flags */, 0 /*suspend */, 0 /*resume */, PS_fillbox, PS_linewidth, #ifdef USE_MOUSE 0, 0, 0, 0, 0, /* no mouse support for postscript */ #endif PS_make_palette, PS_previous_palette, EPSLATEX_set_color, PS_filled_polygon, #ifdef WITH_IMAGE PS_image, #endif 0, 0, 0, /* Enhanced text mode not used */ EPSLATEX_layer, /* Used to signal front/back text */ PS_path TERM_TABLE_END(epslatex_driver) #undef LAST_TERM #define LAST_TERM epslatex_driver TERM_TABLE_START(pslatex_driver) "pslatex", "LaTeX picture environment with PostScript \\specials", PS_XMAX, PS_YMAX, PSTEX_VCHAR, PSTEX_HCHAR, PS_VTIC, PS_HTIC, PS_options, PS_init, PSLATEX_reset, PSTEX_text, null_scale, PS_graphics, PS_move, PS_vector, PS_linetype, PSTEX_put_text, PS_text_angle, PS_justify_text, PS_point, PS_arrow, set_font_null, PS_pointsize, TERM_CAN_CLIP /*flags */ , 0 /*suspend */ , 0 /*resume */ , PS_fillbox, PS_linewidth #ifdef USE_MOUSE , 0, 0, 0, 0, 0 /* no mouse support for postscript */ #endif , PS_make_palette, PS_previous_palette, /* write grestore */ PS_set_color, PS_filled_polygon #ifdef WITH_IMAGE , PS_image , 0, 0, 0 /* No enhanced text mode because this is LaTeX */ , 0 /* layer */ , PS_path #endif TERM_TABLE_END(pslatex_driver) #undef LAST_TERM #define LAST_TERM pslatex_driver TERM_TABLE_START(pstex_driver) "pstex", "plain TeX with PostScript \\specials", PS_XMAX, PS_YMAX, PSTEX_VCHAR, PSTEX_HCHAR, PS_VTIC, PS_HTIC, PS_options, PS_init, PSLATEX_reset, PSTEX_text, null_scale, PS_graphics, PS_move, PS_vector, PS_linetype, PSTEX_put_text, PS_text_angle, PS_justify_text, PS_point, PS_arrow, set_font_null, PS_pointsize, TERM_CAN_CLIP /*flags */ , 0 /*suspend */ , 0 /*resume */ , PS_fillbox, PS_linewidth #ifdef USE_MOUSE , 0, 0, 0, 0, 0 /* no mouse support for postscript */ #endif , PS_make_palette, PS_previous_palette, /* write grestore */ PS_set_color, PS_filled_polygon #ifdef WITH_IMAGE , PS_image #endif , 0, 0, 0 /* No enhanced text mode because this is LaTeX */ , 0 /* layer */ , PS_path TERM_TABLE_END(pstex_driver) #undef LAST_TERM #define LAST_TERM pstex_driver #endif /* TERM_TABLE */ #endif /* TERM_PROTO_ONLY */