/* Hello, Emacs, this is -*-C-*- */
/* GNUPLOT - texdraw.trm */
/*[
* Copyright 1990 - 1993, 1998, 2004, 2018
*
* 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 terminal driver supports:
* The TEXDRAW macros for LaTeX.
*
* AUTHORS
* Khun Yee Fung. Modified from eepic.trm.
* clipper@csd.uwo.ca
* January 20, 1992
*
* Bastian Maerkisch
*
* send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
*
*/
/*
* This file contains the texdraw terminal driver, intended for use with the
* texdraw macro package for LaTeX. This is an alternative to the
* latex driver. You need texdraw.sty, and texdraw.tex in the texdraw package.
*
*/
#include "driver.h"
#ifdef TERM_REGISTER
register_term(texdraw)
#endif
#ifdef TERM_PROTO
TERM_PUBLIC void TEXDRAW_init(void);
TERM_PUBLIC void TEXDRAW_options(void);
TERM_PUBLIC void TEXDRAW_graphics(void);
TERM_PUBLIC void TEXDRAW_text(void);
TERM_PUBLIC void TEXDRAW_reset(void);
TERM_PUBLIC void TEXDRAW_linetype(int linetype);
TERM_PUBLIC void TEXDRAW_dashtype(int dt, t_dashtype *custom_dash_pattern);
TERM_PUBLIC void TEXDRAW_linewidth(double linewidth);
TERM_PUBLIC void TEXDRAW_move(unsigned int x, unsigned int y);
TERM_PUBLIC void TEXDRAW_pointsize(double size);
TERM_PUBLIC void TEXDRAW_point(unsigned int x, unsigned int y, int number);
TERM_PUBLIC void TEXDRAW_vector(unsigned int ux, unsigned int uy);
TERM_PUBLIC void TEXDRAW_arrow(unsigned int sx, unsigned int sy,
unsigned int ex, unsigned int ey,
int head);
TERM_PUBLIC void TEXDRAW_put_text(unsigned int x, unsigned int y, const char str[]);
TERM_PUBLIC int TEXDRAW_justify_text(enum JUSTIFY mode);
TERM_PUBLIC int TEXDRAW_text_angle(float ang);
TERM_PUBLIC void TEXDRAW_set_color(t_colorspec *colorspec);
TERM_PUBLIC int TEXDRAW_make_palette(t_sm_palette *);
TERM_PUBLIC void TEXDRAW_set_color(t_colorspec *);
TERM_PUBLIC void TEXDRAW_fillbox(int style,
unsigned int x1, unsigned int y1,
unsigned int width, unsigned int height);
TERM_PUBLIC void TEXDRAW_filled_polygon(int points, gpiPoint *corners);
#define TEXDRAW_PTS_PER_INCH (72.27)
/* resolution of printer we expect to use */
#define DOTS_PER_INCH (300)
/* dot size in pt */
#define TEXDRAW_UNIT (TEXDRAW_PTS_PER_INCH/DOTS_PER_INCH)
/* 5 inches wide by 3 inches high (default) */
#define TEXDRAW_XMAX (5*DOTS_PER_INCH)
#define TEXDRAW_YMAX (3*DOTS_PER_INCH)
#define TEXDRAW_HTIC (5*DOTS_PER_INCH/72) /* (5./TEXDRAW_UNIT) */
#define TEXDRAW_VTIC (5*DOTS_PER_INCH/72) /* (5./TEXDRAW_UNIT) */
#define TEXDRAW_HCHAR (DOTS_PER_INCH*53/10/72) /* (5.3/TEXDRAW_UNIT) */
#define TEXDRAW_VCHAR (DOTS_PER_INCH*11/72) /* (11./TEXDRAW_UNIT) */
#define GOT_TEXDRAW_PROTO
#endif
#ifndef TERM_PROTO_ONLY
#ifdef TERM_BODY
/* terminate any line in progress */
static void TEXDRAW_endline(void);
/* determine gray level according to fillstyle */
static double TEXDRAW_fill_gray(int style);
static unsigned int TEXDRAW_posx;
static unsigned int TEXDRAW_posy;
static enum JUSTIFY TEXDRAW_justify = LEFT;
static enum JUSTIFY TEXDRAW_last_justify = LEFT;
static int TEXDRAW_angle = 0;
static float TEXDRAW_scalefactor = 0.2409;
static double TEXDRAW_xscale = 1.0, TEXDRAW_yscale = 1.0;
/* for DOTS point style */
#define TEXDRAW_TINY_DOT "\\htext{$\\cdot$}"
/* POINTS */
#define TEXDRAW_POINT_TYPES 15 /* we supply more point types */
static const char * TEXDRAW_points[TEXDRAW_POINT_TYPES] = {
"\\htext{%s$+$}",
"\\htext{%s$\\times$}",
"\\htext{%s$\\ast$}",
"\\rmove(0 -8)\\htext{%s$\\Box$}",
"\\htext{%s$\\blacksquare$}",
"\\htext{%s$\\circ$}",
"\\htext{%s$\\bullet$}",
"\\htext{%s$\\triangle$}",
"\\htext{%s$\\blacktriangle$}",
"\\htext{%s$\\triangledown$}",
"\\htext{%s$\\blacktriangledown$}",
"\\htext{%s$\\lozenge$}",
"\\htext{%s$\\blacklozenge$}",
"\\htext{%s$\\heartsuit$}",
"\\htext{%s$\\spadesuit$}",
};
/* LINES */
#define TEXDRAW_NUMLINES 5 /* number of linetypes below */
static const int TEXDRAW_lines[] = {
2, /* -2 border */
1, /* -1 axes */
2, /* 0 solid */
2, /* 1 solid */
2, /* 2 solid */
};
#define TEXDRAW_NUMPAT 5
static const int TEXDRAW_dashpat[][6] = {
{ 10, 6, 0, 0, 0, 0 },
{ 4, 8, 0, 0, 0, 0 },
{ 10, 6, 4, 6, 0, 0 },
{ 10, 6, 4, 6, 4, 6 },
};
/* The line type selected most recently */
static int TEXDRAW_last_type = 0;
/* current line type */
static int TEXDRAW_type;
/* are we in the middle of a line */
static TBOOLEAN TEXDRAW_inline = FALSE;
/* number of points in line so far */
static int TEXDRAW_linecount = 0;
/* max value for linecount */
#define TEXDRAW_LINEMAX 5
/* linewidth scale factor */
static double TEXDRAW_lw;
static double TEXDRAW_last_lw;
/* dashtype */
static int TEXDRAW_dt;
/* ARROWS */
static char TEXDRAW_arrow_type;
static int TEXDRAW_arrow_length;
static int TEXDRAW_arrow_width;
/* GRAY LEVEL */
static double TEXDRAW_gray;
static double TEXDRAW_last_gray;
/* OPTIONS */
static TBOOLEAN TEXDRAW_standalone = FALSE;
static TBOOLEAN TEXDRAW_rounded = TRUE;
static TBOOLEAN TEXDRAW_colortext = FALSE;
static TBOOLEAN TEXDRAW_psarrows = TRUE;
static TBOOLEAN TEXDRAW_texpoints = TRUE;
static size_units TEXDRAW_explicit_units = INCHES;
static double TEXDRAW_size_x = 5.;
static double TEXDRAW_size_y = 3.;
static double TEXDRAW_lw_scale = 1.;
static double TEXDRAW_ps = 1.;
static double TEXDRAW_background = 1.;
/* option names */
enum TEXDRAW_id { TEXDRAW_DEFAULT,
TEXDRAW_SIZE,
TEXDRAW_STANDALONE, TEXDRAW_INPUT,
TEXDRAW_BLACKTEXT, TEXDRAW_COLORTEXT,
TEXDRAW_ROUNDED, TEXDRAW_BUTT,
TEXDRAW_LINEWIDTH, TEXDRAW_POINTSCALE,
TEXDRAW_PSARROWS, TEXDRAW_GPARROWS,
TEXDRAW_TEXPOINTS, TEXDRAW_GPPOINTS,
TEXDRAW_BACKGROUND,
TEXDRAW_OTHER };
static struct gen_table TEXDRAW_opts[] =
{
{ "def$ault", TEXDRAW_DEFAULT },
{ "size", TEXDRAW_SIZE },
{ "stand$alone", TEXDRAW_STANDALONE },
{ "inp$ut", TEXDRAW_INPUT },
{ "b$lacktext", TEXDRAW_BLACKTEXT },
{ "colort$ext", TEXDRAW_COLORTEXT },
{ "colourt$ext", TEXDRAW_COLORTEXT },
{ "round$ed", TEXDRAW_ROUNDED },
{ "butt", TEXDRAW_BUTT },
{ "backg$round", TEXDRAW_BACKGROUND },
{ "lw", TEXDRAW_LINEWIDTH },
{ "linew$idth", TEXDRAW_LINEWIDTH },
{ "points$cale", TEXDRAW_POINTSCALE },
{ "ps", TEXDRAW_POINTSCALE },
{ "psarrows", TEXDRAW_PSARROWS },
{ "gparrows", TEXDRAW_GPARROWS },
{ "texpoints", TEXDRAW_TEXPOINTS },
{ "gppoints", TEXDRAW_GPPOINTS },
{ NULL, TEXDRAW_OTHER }
};
TERM_PUBLIC void
TEXDRAW_options()
{
char size_str[80] = "";
int bg;
while (!END_OF_COMMAND) {
switch ((enum TEXDRAW_id) lookup_table(&TEXDRAW_opts[0], c_token)) {
case TEXDRAW_DEFAULT:
TEXDRAW_standalone = FALSE;
TEXDRAW_rounded = TRUE;
TEXDRAW_colortext = TRUE;
TEXDRAW_psarrows = TRUE;
TEXDRAW_texpoints = TRUE;
TEXDRAW_lw_scale = TEXDRAW_ps = 1.;
TEXDRAW_background = 1.;
TEXDRAW_size_x = 5 ;
TEXDRAW_size_y = 3.;
term->xmax = TEXDRAW_size_x * DOTS_PER_INCH;
term->ymax = TEXDRAW_size_y * DOTS_PER_INCH;
term->v_char = TEXDRAW_VCHAR;
term->v_tic = TEXDRAW_VTIC;
break;
case TEXDRAW_SIZE: {
float width, height;
c_token++;
TEXDRAW_explicit_units = parse_term_size(&width, &height, INCHES);
TEXDRAW_size_x = width / gp_resolution;
TEXDRAW_size_y = height / gp_resolution;
term->xmax = TEXDRAW_size_x * DOTS_PER_INCH;
term->ymax = TEXDRAW_size_y * DOTS_PER_INCH;
term->v_char = TEXDRAW_VCHAR;
term->v_tic = TEXDRAW_VTIC;
break;
}
case TEXDRAW_STANDALONE:
TEXDRAW_standalone = TRUE;
c_token++;
break;
case TEXDRAW_INPUT:
TEXDRAW_standalone = FALSE;
c_token++;
break;
case TEXDRAW_COLORTEXT:
TEXDRAW_colortext = TRUE;
c_token++;
break;
case TEXDRAW_BLACKTEXT:
TEXDRAW_colortext = FALSE;
c_token++;
break;
case TEXDRAW_BUTT:
TEXDRAW_rounded = FALSE;
c_token++;
break;
case TEXDRAW_ROUNDED:
TEXDRAW_rounded = TRUE;
c_token++;
break;
case TEXDRAW_LINEWIDTH:
c_token++;
TEXDRAW_lw_scale = real_expression();
if (TEXDRAW_lw_scale < 0.0)
TEXDRAW_lw_scale = 1.0;
break;
case TEXDRAW_POINTSCALE:
c_token++;
TEXDRAW_ps = real_expression();
if (TEXDRAW_ps < 0.0)
TEXDRAW_ps = 1.0;
break;
case TEXDRAW_BACKGROUND: {
int background;
int red, green, blue;
c_token++;
background = parse_color_name();
red = (double)((background >> 16) & 0xff);
green = (double)((background >> 8) & 0xff);
blue = (double)( background & 0xff);
TEXDRAW_background = (red * 0.30 + green * 0.59 + blue * 0.11) / 255;
break;
}
case TEXDRAW_GPARROWS:
c_token++;
TEXDRAW_psarrows = FALSE;
break;
case TEXDRAW_PSARROWS:
c_token++;
TEXDRAW_psarrows = TRUE;
break;
case TEXDRAW_GPPOINTS:
c_token++;
TEXDRAW_texpoints = FALSE;
break;
case TEXDRAW_TEXPOINTS:
c_token++;
TEXDRAW_texpoints = TRUE;
break;
default:
int_error(c_token, "Unknown terminal option");
}
}
if (TEXDRAW_explicit_units == INCHES)
snprintf(size_str, sizeof(size_str), "size %.2fin, %.2fin", TEXDRAW_size_x, TEXDRAW_size_y);
else if (TEXDRAW_explicit_units == CM)
snprintf(size_str, sizeof(size_str), "size %.2fcm, %.2fcm", TEXDRAW_size_x * 2.54, TEXDRAW_size_y * 2.54);
// update terminal option string
bg = TEXDRAW_background * 255;
snprintf(term_options, MAX_LINE_LEN + 1,
"%s linewidth %.1f pointscale %.1f %stext "
"background \"#%02x%02x%02x\" "
"%sarrows %spoints %s",
TEXDRAW_rounded ? "rounded" : "butt",
TEXDRAW_lw_scale, TEXDRAW_ps,
TEXDRAW_colortext ? "color" : "black",
bg, bg, bg,
TEXDRAW_psarrows ? "ps" : "gp",
TEXDRAW_texpoints ? "tex" : "gp",
TEXDRAW_standalone ? "standalone" : "input");
}
TERM_PUBLIC void
TEXDRAW_init()
{
fputs("%% GNUPLOT: LaTeX using TEXDRAW macros\n", gpoutfile);
if (TEXDRAW_standalone) {
fputs(
"\\documentclass[a4paper,10pt]{article}\n"\
"\\usepackage{texdraw}\n"\
"\\usepackage{latexsym}\n"\
"\\usepackage{amssymb}\n"\
"\\usepackage{xcolor}\n"
"\\begin{document}\n",
gpoutfile);
}
}
TERM_PUBLIC void
TEXDRAW_graphics()
{
static char tdg1[] = "\
\\btexdraw\n\
\\ifx\\pathDEFINED\\relax\\else\\let\\pathDEFINED\\relax\n\
\\def\\QtGfr{\\ifx (\\TGre \\let\\YhetT\\cpath\\else\\let\\YhetT\\relax\\fi\\YhetT}\n\
\\def\\path (#1 #2){\\move (#1 #2)\\futurelet\\TGre\\QtGfr}\n\
\\def\\cpath (#1 #2){\\lvec (#1 #2)\\futurelet\\TGre\\QtGfr}\n\
\\fi\n\
\\drawdim pt\n\
\\setunitscale %2.2f\n\
\\linewd %d\n\
\\textref h:L v:C\n\
\\writeps{%d setlinecap} \\writeps{%d setlinejoin}\n";
if (TEXDRAW_standalone)
fputs("\\begin{figure}\n", gpoutfile);
fprintf(gpoutfile, tdg1,
TEXDRAW_scalefactor,
TEXDRAW_lines[2],
TEXDRAW_rounded ? 1 : 0, TEXDRAW_rounded ? 1 : 0
);
if (TEXDRAW_background == 1.) {
/* enforce bounding box */
fprintf(gpoutfile, "\\move (0 0) \\rmove (%d %d)\n",
term->xmax, term->ymax);
} else {
fprintf(gpoutfile, "\\move (0 0) \\rlvec (%d 0) \\rlvec (0 %d) \\rlvec (%d 0) \\ifill f:%0.2f\n",
term->xmax, term->ymax, - (int) term->xmax,
TEXDRAW_background);
}
TEXDRAW_last_type = 0;
TEXDRAW_type = 0;
TEXDRAW_posx = TEXDRAW_posy = 0;
TEXDRAW_lw = TEXDRAW_last_lw = 1.;
TEXDRAW_gray = TEXDRAW_last_gray = 0.;
TEXDRAW_arrow_type = 0;
TEXDRAW_arrow_length = -1;
TEXDRAW_arrow_width = -1;
TEXDRAW_justify = TEXDRAW_last_justify = LEFT;
}
TERM_PUBLIC void
TEXDRAW_text()
{
TEXDRAW_endline();
// fputs("\\drawbb\n", gpoutfile);
fputs("\\etexdraw\n", gpoutfile);
if (TEXDRAW_standalone)
fputs("\\end{figure}\n\n", gpoutfile);
}
TERM_PUBLIC void
TEXDRAW_reset()
{
TEXDRAW_endline();
TEXDRAW_posx = TEXDRAW_posy = 0;
if (TEXDRAW_standalone)
fputs("\\end{document}\n", gpoutfile);
}
TERM_PUBLIC void
TEXDRAW_linetype(int linetype)
{
TEXDRAW_endline();
if (linetype >= TEXDRAW_NUMLINES - 2)
linetype %= (TEXDRAW_NUMLINES - 2);
TEXDRAW_type = linetype > -2 ? linetype : LT_BLACK;
if (linetype == LT_AXIS)
TEXDRAW_dashtype(DASHTYPE_AXIS, NULL);
else
TEXDRAW_dashtype(DASHTYPE_SOLID, NULL);
}
TERM_PUBLIC void
TEXDRAW_dashtype(int dt, t_dashtype *custom_dash_pattern)
{
TEXDRAW_endline();
if (dt == DASHTYPE_SOLID) {
dt = 0;
} else if (dt == DASHTYPE_AXIS) {
dt = 2;
} else if (dt > 0) {
dt %= TEXDRAW_NUMPAT;
}
if (dt == TEXDRAW_dt)
return;
if (dt == 0) {
fputs("\\lpatt ()\n", gpoutfile);
TEXDRAW_dt = 0;
} else if (dt > 0) {
int i;
fputs("\\lpatt (", gpoutfile);
for (i = 0; i < 6; i++) {
if (TEXDRAW_dashpat[dt - 1][i] == 0)
break;
fprintf(gpoutfile, "%d ", (int) (TEXDRAW_dashpat[dt - 1][i] * TEXDRAW_lw));
}
fputs(")\n", gpoutfile);
TEXDRAW_dt = dt;
} else if (dt == DASHTYPE_CUSTOM) {
/* not supported (yet) */
}
}
TERM_PUBLIC void
TEXDRAW_linewidth(double linewidth)
{
TEXDRAW_lw = linewidth * TEXDRAW_lw_scale;
}
TERM_PUBLIC void
TEXDRAW_move(unsigned int x, unsigned int y)
{
TEXDRAW_endline();
TEXDRAW_posx = x;
TEXDRAW_posy = y;
}
TERM_PUBLIC void
TEXDRAW_pointsize(double size)
{
// We can only scale gnuplot's native point types
term_pointsize = (size >= 0 ? size * TEXDRAW_ps : 1);
}
TERM_PUBLIC void
TEXDRAW_point(unsigned int x, unsigned int y, int number)
{
char colorstr[80] = "";
TEXDRAW_move(x, y);
if (!TEXDRAW_texpoints) {
do_point(x, y, number);
return;
}
/* Print the character defined by 'number'; number < 0 means
* to use a dot, otherwise one of the defined points. */
fprintf(gpoutfile, "\\move (%d %d)\n",
(int) ((double) x * TEXDRAW_xscale),
(int) ((double) y * TEXDRAW_yscale));
if (TEXDRAW_last_justify != CENTRE) {
fprintf(gpoutfile, "\\textref h:C v:C ");
TEXDRAW_last_justify = CENTRE;
}
if (TEXDRAW_colortext && TEXDRAW_gray != 0)
snprintf(colorstr, sizeof(colorstr), "\\color{black!%d!}", 100 - (int) (TEXDRAW_gray * 100));
if (number < 0) {
fprintf(gpoutfile, "%s\n", TEXDRAW_TINY_DOT);
} else {
fprintf(gpoutfile, TEXDRAW_points[number % TEXDRAW_POINT_TYPES], colorstr);
fputc('\n', gpoutfile);
}
}
TERM_PUBLIC void
TEXDRAW_vector(unsigned int ux, unsigned int uy)
{
if (!TEXDRAW_inline) {
TEXDRAW_inline = TRUE;
/* Start a new line. This depends on line type */
if ((TEXDRAW_type != TEXDRAW_last_type) || (TEXDRAW_last_lw != TEXDRAW_lw)) {
if (TEXDRAW_lines[TEXDRAW_type + 2] * TEXDRAW_lw != TEXDRAW_lines[TEXDRAW_last_type + 2] * TEXDRAW_last_lw)
fprintf(gpoutfile, "\\linewd %d\n",
(int) (TEXDRAW_lines[TEXDRAW_type + 2] * TEXDRAW_lw + 0.5));
TEXDRAW_last_type = TEXDRAW_type;
TEXDRAW_last_lw = TEXDRAW_lw;
}
if (TEXDRAW_gray != TEXDRAW_last_gray) {
fprintf(gpoutfile, "\\setgray %0.2f\n", TEXDRAW_gray);
TEXDRAW_last_gray = TEXDRAW_gray;
}
fprintf(gpoutfile, "\\path (%d %d)",
(int) ((double) TEXDRAW_posx * TEXDRAW_xscale),
(int) ((double) TEXDRAW_posy * TEXDRAW_yscale));
TEXDRAW_linecount = 1;
} else {
/* Even though we are in middle of a path,
* we may want to start a new path command.
* If they are too long then latex will choke.
*/
if (TEXDRAW_linecount++ >= TEXDRAW_LINEMAX) {
fputs("\n\\cpath ", gpoutfile);
TEXDRAW_linecount = 1;
}
}
fprintf(gpoutfile, "(%d %d)",
(int) ((double) ux * TEXDRAW_xscale),
(int) ((double) uy * TEXDRAW_yscale));
TEXDRAW_posx = ux;
TEXDRAW_posy = uy;
}
static void
TEXDRAW_endline()
{
if (TEXDRAW_inline) {
putc('\n', gpoutfile);
TEXDRAW_inline = FALSE;
}
}
TERM_PUBLIC void
TEXDRAW_arrow(
unsigned int sx, unsigned int sy,
unsigned int ex, unsigned int ey,
int head)
{
char text;
char type = 'T'; // empty triangle
// These are the default arrow sizes:
int tiplen = (0.16 * 72 / TEXDRAW_scalefactor + 0.5);
int width = (0.08 * 72 / TEXDRAW_scalefactor + 0.5);
// Texdraw cannot only draw vector heads, fall back to built-in code.
if (!TEXDRAW_psarrows || (head & HEADS_ONLY)) {
do_arrow(sx, sy, ex, ey, head);
return;
}
switch (curr_arrow_headfilled) {
case AS_NOFILL:
type = 'V'; // open V-shape
break;
case AS_FILLED:
case AS_NOBORDER:
type = 'F'; // filled triangle
break;
case AS_EMPTY:
type = 'W'; // white filled triangle
break;
}
if (curr_arrow_headlength > 0) {
width = sin(curr_arrow_headangle * DEG2RAD) * curr_arrow_headlength;
tiplen = cos(curr_arrow_headangle * DEG2RAD) * curr_arrow_headlength;
if ((curr_arrow_headbackangle - curr_arrow_headangle) type) {
case TC_FRAC:
TEXDRAW_gray = colorspec->value;
break;
case TC_RGB: {
int red, green, blue;
red = (colorspec->lt >> 16) & 0xff;
green = (colorspec->lt >> 8) & 0xff;
blue = (colorspec->lt ) & 0xff;
TEXDRAW_gray = (red * 0.30 + green * 0.59 + blue * 0.11) / 255;
break;
}
case TC_LT:
/* any line type is black for now */
TEXDRAW_gray = 0.;
break;
default:
break;
}
}
static double
TEXDRAW_fill_gray(int style)
{
double gray = TEXDRAW_gray;
int pattern = style >> 4;
int frac = style >> 4;
static const double TEXDRAW_pat_gray[4] = {
1.0, 0.5, 0.8, 0.0
};
switch (style & 0x0f) {
case FS_SOLID:
case FS_TRANSPARENT_SOLID:
if (frac < 100)
gray *= frac / 100.;
break;
case FS_PATTERN:
case FS_TRANSPARENT_PATTERN:
gray = TEXDRAW_pat_gray[pattern % 4];
break;
case FS_EMPTY:
gray = 1.0;
break;
case FS_DEFAULT:
default:
break;
}
return gray;
}
TERM_PUBLIC void
TEXDRAW_fillbox(int style,
unsigned int x1, unsigned int y1,
unsigned int width, unsigned int height)
{
double gray;
TEXDRAW_endline();
gray = TEXDRAW_fill_gray(style);
// outline box using relative moves
fprintf(gpoutfile, "\\move (%d %d)", x1, y1);
fprintf(gpoutfile, "\\rlvec (%d %d)", width, 0);
fprintf(gpoutfile, "\\rlvec (%d %d)", 0, height);
fprintf(gpoutfile, "\\rlvec (%d %d)", - (int) width, 0);
// the polygon is closed automatically by fill
fprintf(gpoutfile, "\\ifill f:%0.2f\n", gray);
}
TERM_PUBLIC void
TEXDRAW_filled_polygon(int points, gpiPoint *corners)
{
double gray;
int i;
TEXDRAW_endline();
gray = TEXDRAW_fill_gray(corners->style);
// outline polygon
fprintf(gpoutfile, "\\move (%d %d)", corners[0].x, corners[0].y);
for (i = 1; i < points; i++)
fprintf(gpoutfile, "\\lvec (%d %d)", corners[i].x, corners[i].y);
// fill polygon
fprintf(gpoutfile, "\\ifill f:%0.2f\n", gray);
}
#endif /* TERM_BODY */
#ifdef TERM_TABLE
TERM_TABLE_START(texdraw_driver)
"texdraw",
"LaTeX texdraw environment",
TEXDRAW_XMAX, TEXDRAW_YMAX, TEXDRAW_VCHAR, TEXDRAW_HCHAR,
TEXDRAW_VTIC, TEXDRAW_HTIC, TEXDRAW_options, TEXDRAW_init, TEXDRAW_reset,
TEXDRAW_text, null_scale, TEXDRAW_graphics, TEXDRAW_move, TEXDRAW_vector,
TEXDRAW_linetype, TEXDRAW_put_text, TEXDRAW_text_angle,
TEXDRAW_justify_text, TEXDRAW_point, TEXDRAW_arrow, set_font_null,
TEXDRAW_pointsize,
TERM_IS_LATEX | TERM_LINEWIDTH | TERM_POINTSCALE | TERM_MONOCHROME,
0 /*suspend*/, 0 /*resume*/,
TEXDRAW_fillbox,
TEXDRAW_linewidth,
#ifdef USE_MOUSE
0, 0, 0, 0, 0,
#endif
TEXDRAW_make_palette, 0,
TEXDRAW_set_color,
TEXDRAW_filled_polygon,
0, /* image */
0, 0, 0, /* enhanced text */
0, /* layer */
0, /* path */
0.0, /* scale (unused) */
0, /* hypertext */
0,
0,
TEXDRAW_dashtype
TERM_TABLE_END(texdraw_driver)
#undef LAST_TERM
#define LAST_TERM texdraw_driver
#endif /* TERM_TABLE */
#endif /* TERM_PROTO_ONLY */
#ifdef TERM_HELP
START_HELP(texdraw)
"1 texdraw",
"?commands set terminal texdraw",
"?set terminal texdraw",
"?set term texdraw",
"?terminal texdraw",
"?term texdraw",
"?texdraw",
" The `texdraw` terminal driver supports the (La)TeX texdraw environment. It is",
" intended for use with the texdraw package,",
" see https://www.ctan.org/tex-archive/graphics/texdraw/ .",
"",
" set terminal texdraw",
" {size {unit},{unit}}",
" {standalone | input}",
" {blacktext | colortext | colourtext}",
" {linewidth } {rounded | butt}",
" {pointscale }",
" {psarrows | gparrows} {texpoints | gppoints}",
" {background }",
"",
" Note: Graphics are in grayscale only. Text is always black. Boxes and polygons",
" are filled using solid gray levels only. Patterns are not available.",
"",
" Points, among other things, are drawn using the LaTeX commands \"\\Diamond\" and",
" \"\\Box\". These commands no longer belong to the LaTeX2e core; they are included",
" in the latexsym package, which is part of the base distribution and thus part",
" of any LaTeX implementation. Please do not forget to use this package.",
" Other point types use symbols from the amssymb package. For compatibility with",
" plain TeX you need to specify the `gppoints` option.",
"",
" `standalone` produces a LaTeX file with possibly multiple plots, ready",
" to be compiled. The default is `input` to produce a TeX file which can",
" be included.",
"",
" `blacktext` forces all text to be written in black. `colortext` enables",
" \"colored\" text. The default is `blacktext` and \"color\" means grayscale",
" really.",
"",
" `rounded` sets line caps and line joins to be rounded; `butt` sets butt",
" caps and mitered joins and is the default.",
"",
" `linewidth` and `pointscale` scale the width of lines and the size of point",
" symbols, respectively. `pointscale` only applies to `gppoints`.",
"",
" `psarrows` draws `arrow`s using TeXdraw commands which are shorter but do not",
" offer all options. `gparrows` selects drawing arrows using gnuplot's",
" own routine for full functionality instead. Similarly, `texpoints`, and ",
" `gppoints` select LaTeX symbols or gnuplot's point drawing routines."
END_HELP(texdraw)
#endif /* TERM_HELP */