[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/gnuplot/gnuplot/master/term/cairo.trm [Back]  [Original]

/* Hello, Emacs: this is -*-C-*- ! */

/* GNUPLOT - cairo.trm */

/*[
 * Copyright 2007   Timothee Lecomte
 *
 * 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.
]*/

/*
 * Modifications:
 *	Peter Danenberg, Ethan Merritt	- handle png output as well as pdf
 *	Peter Danenberg - crop for PNGs
 *	Ren Haber - added epscairo terminal
 *	Bastian Maerkisch - cairolatex terminal
 *	Henri Menke - add png option for graphics output
 */

#ifdef TERM_REGISTER
register_term (pdfcairo)
#endif

#ifdef TERM_PROTO
TERM_PUBLIC void cairotrm_options(void);
TERM_PUBLIC void cairotrm_init(void);
TERM_PUBLIC void cairotrm_graphics(void);
TERM_PUBLIC void cairotrm_text(void);
TERM_PUBLIC void cairotrm_linetype(int linetype);
TERM_PUBLIC void cairotrm_move(unsigned int x, unsigned int y);
TERM_PUBLIC void cairotrm_vector(unsigned int x, unsigned int y);
TERM_PUBLIC void cairotrm_put_text(unsigned int x, unsigned int y, const char *str);
TERM_PUBLIC void cairotrm_enhanced_flush(void);
TERM_PUBLIC void cairotrm_enhanced_writec(int c);
TERM_PUBLIC void cairotrm_enhanced_open(char* fontname, double fontsize, double base, TBOOLEAN widthflag, TBOOLEAN showflag, int overprint);
TERM_PUBLIC void cairotrm_reset(void);
TERM_PUBLIC int cairotrm_justify_text(enum JUSTIFY mode);
TERM_PUBLIC void cairotrm_point(unsigned int x, unsigned int y, int pointstyle);
TERM_PUBLIC void cairotrm_linewidth(double linewidth);
TERM_PUBLIC int cairotrm_text_angle(float ang);
TERM_PUBLIC void cairotrm_fillbox(int style, unsigned int x1, unsigned int y1, unsigned int width, unsigned int height);
TERM_PUBLIC int cairotrm_set_font(const char *font);
TERM_PUBLIC void cairotrm_pointsize(double ptsize);
TERM_PUBLIC void cairotrm_image(unsigned int M, unsigned int N, coordval * image, gpiPoint * corner, t_imagecolor color_mode);
TERM_PUBLIC int cairotrm_make_palette(t_sm_palette *palette);
TERM_PUBLIC void cairotrm_set_color(t_colorspec *colorspec);
TERM_PUBLIC void cairotrm_filled_polygon(int n, gpiPoint * corners);
TERM_PUBLIC void cairotrm_boxed_text(unsigned int x, unsigned int y, int option);
TERM_PUBLIC void cairotrm_dashtype(int type, t_dashtype *custom_dash_pattern);

#ifdef HAVE_WEBP
TERM_PUBLIC void WEBP_options(int);	/* We call it from cairotrm_options */
#endif

#endif /* TERM_PROTO */

#ifndef TERM_PROTO_ONLY

#ifdef TERM_BODY

#include "cairo-pdf.h"
#ifdef HAVE_CAIROEPS
#include "cairo-ps.h"
#endif
#include "wxterminal/gp_cairo.h"
#include "wxterminal/gp_cairo_helpers.h"
#include "glib.h"		/* For guint32 */

#define CAIROTRM_DEFAULT_FONTNAME "Sans"

static cairo_status_t cairostream_write(void *closure, unsigned char *data, unsigned int length);
static int cairostream_error[1];

/* Terminal id */
enum CAIROTRM_id {
    CAIROTRM_FONT,
    CAIROTRM_FONTSCALE,
    CAIROTRM_ENHANCED,
    CAIROTRM_NOENHANCED,
    CAIROTRM_SIZE,
    CAIROTRM_ROUNDED,
    CAIROTRM_BUTT,
    CAIROTRM_SQUARE,
    CAIROTRM_LINEWIDTH,
    CAIROTRM_DASHED,
    CAIROTRM_SOLID,
    CAIROTRM_MONO,
    CAIROTRM_COLOR,
    CAIROTRM_DASHLENGTH,
    CAIROTRM_TRANSPARENT,
    CAIROTRM_NOTRANSPARENT,
    CAIROTRM_CROP,
    CAIROTRM_NOCROP,
    CAIROTRM_BACKGROUND,
    CAIROTRM_POINTSCALE,
    CAIROLATEX_STANDALONE,
    CAIROLATEX_INPUT,
    CAIROLATEX_HEADER,
    CAIROLATEX_NOHEADER,
    CAIROLATEX_BLACKTEXT,
    CAIROLATEX_COLORTEXT,
    CAIROLATEX_EPS,
    CAIROLATEX_PDF,
    CAIROLATEX_PNG,
    CAIROLATEX_PNG_RESOLUTION,
    CAIROTRM_OTHER
};

/* Terminal type of postscript dialect */
enum CAIRO_TERMINALTYPE {
    CAIROTERM_EPS, CAIROTERM_PDF, CAIROTERM_PNG, CAIROTERM_LATEX
};

/* One struct that takes all terminal parameters
 * by Harald Harders  */
typedef struct cairo_params_t {
    enum CAIRO_TERMINALTYPE terminal;
    size_units explicit_units;
    TBOOLEAN enhanced;
    TBOOLEAN dashed;
    float dash_length;
    rgb_color background;	/* struct with r/g/b [0.0:1.0] */
    unsigned int rgb_bkgnd;	/* same thing packe into 24bits */
    TBOOLEAN mono;
    t_linecap linecap;		/* butt/rounded/square linecaps and linejoins */
    TBOOLEAN transparent;
    TBOOLEAN crop;
    char *fontname;		/* name of font */
    float fontsize;		/* size of font in pts */
    float fontscale;		/* modified by this */
    float width;
    float height;
    float base_linewidth;
    float lw;
    float ps;
    enum CAIROTRM_id output;	/* format of the graphics produced by cairolatex */
    int resolution;             /* in dpi; CAIROLATEX_PNG only */
    TBOOLEAN anchor;		/* TRUE = anchor kitty output to top left */
} cairo_params_t;

#define CAIROEPS_PARAMS_DEFAULT { \
    CAIROTERM_EPS, INCHES, FALSE, FALSE, 1.0, {1.,1.,1.}, 0xffffff, \
    FALSE, BUTT, TRUE, FALSE, NULL, \
    12, 0.5, 5*72., 3*72., 0.25, 1.0, 1.0, FALSE \
}
static cairo_params_t cairoeps_params = CAIROEPS_PARAMS_DEFAULT;
static const cairo_params_t cairoeps_params_default = CAIROEPS_PARAMS_DEFAULT;

#ifdef HAVE_CAIROEPS
#define CAIROLATEX_PARAMS_DEFAULT { \
    CAIROTERM_LATEX, INCHES, FALSE, FALSE, 1.0, {1.,1.,1.}, 0xffffff, \
    FALSE, BUTT, TRUE, FALSE, NULL, \
    11, 0.6, 5*72., 3*72., 0.25, 1.0, 1.0, FALSE, 300 \
}
#else
#define CAIROLATEX_PARAMS_DEFAULT { \
    CAIROTERM_LATEX, INCHES, FALSE, FALSE, 1.0, {1.,1.,1.}, 0xffffff, \
    FALSE, BUTT, TRUE, FALSE, NULL, \
    11, 0.6, 5*72., 3*72., 0.25, 1.0, 1.0, TRUE, 300 \
}
#endif
static cairo_params_t cairolatex_params = CAIROLATEX_PARAMS_DEFAULT;
static const cairo_params_t cairolatex_params_default = CAIROLATEX_PARAMS_DEFAULT;

#define CAIROPDF_PARAMS_DEFAULT { \
    CAIROTERM_PDF, INCHES, FALSE, FALSE, 1.0, {1.,1.,1.}, 0xffffff, \
    FALSE, BUTT, TRUE, FALSE, NULL, \
    12, 0.5, 5*72., 3*72., 0.25, 1.0, 1.0, FALSE \
}
static cairo_params_t cairopdf_params = CAIROPDF_PARAMS_DEFAULT;
static const cairo_params_t cairopdf_params_default = CAIROPDF_PARAMS_DEFAULT;

#define CAIROPNG_PARAMS_DEFAULT { \
    CAIROTERM_PNG, PIXELS, FALSE, FALSE, 1.0, {1.,1.,1.}, 0xffffff, \
    FALSE, BUTT, FALSE, FALSE, NULL, \
    12, 1.0, 640., 480., 1.0, 1.0, 1.0, FALSE, 0, TRUE\
}
static cairo_params_t cairopng_params = CAIROPNG_PARAMS_DEFAULT;
static const cairo_params_t cairopng_params_default = CAIROPNG_PARAMS_DEFAULT;

static cairo_params_t *cairo_params = &cairopdf_params;
static const cairo_params_t *cairo_params_default = &cairopdf_params;

#ifdef PSLATEX_DRIVER
#define ISCAIROLATEX (cairo_params->terminal == CAIROTERM_LATEX)
static ps_params_t cairo_epslatex_params = EPSLATEX_PARAMS_DEFAULT;
#else
#define ISCAIROLATEX (FALSE)
#endif

char *cairo_enhanced_fontname = NULL;

plot_struct plot;

static struct gen_table cairotrm_opts[] = {
    {"fontscale",   CAIROTRM_FONTSCALE},
    {"f$ont",   CAIROTRM_FONT},
    {"enh$anced", CAIROTRM_ENHANCED},
    {"noenh$anced", CAIROTRM_NOENHANCED},
    {"si$ze", CAIROTRM_SIZE},
    {"round$ed", CAIROTRM_ROUNDED},
    {"butt", CAIROTRM_BUTT},
    {"square", CAIROTRM_SQUARE},
    {"lw", CAIROTRM_LINEWIDTH},
    {"linew$idth", CAIROTRM_LINEWIDTH},
    {"pointscale", CAIROTRM_POINTSCALE},
    {"ps", CAIROTRM_POINTSCALE},
    {"dash$ed", CAIROTRM_DASHED},
    {"solid", CAIROTRM_SOLID},
    {"mono$chrome", CAIROTRM_MONO},
    {"color", CAIROTRM_COLOR},
    {"col$our", CAIROTRM_COLOR},
    {"dl", CAIROTRM_DASHLENGTH},
    {"dashl$ength", CAIROTRM_DASHLENGTH},
    {"transp$arent", CAIROTRM_TRANSPARENT},
    {"notransp$arent", CAIROTRM_NOTRANSPARENT},
    {"crop", CAIROTRM_CROP},
    {"nocrop", CAIROTRM_NOCROP},
    {"backg$round", CAIROTRM_BACKGROUND},
    {"nobackg$round", CAIROTRM_TRANSPARENT},
    {"stand$alone", CAIROLATEX_STANDALONE},
    {"inp$ut", CAIROLATEX_INPUT},
    {"header", CAIROLATEX_HEADER},
    {"noheader", CAIROLATEX_NOHEADER},
    {"b$lacktext", CAIROLATEX_BLACKTEXT},
    {"colort$ext", CAIROLATEX_COLORTEXT},
    {"colourt$ext", CAIROLATEX_COLORTEXT},
    {"eps", CAIROLATEX_EPS},
    {"pdf", CAIROLATEX_PDF},
    {"png", CAIROLATEX_PNG},
    {"resolution", CAIROLATEX_PNG_RESOLUTION},
    {NULL, CAIROTRM_OTHER}
};

/* "Called when terminal type is selected. This procedure should parse options on the command line.
* A list of the currently selected options should be stored in term_options[],
* in a form suitable for use with the set term command.
* term_options[] is used by the save command.  Use options_null() if no options are available." */
TERM_PUBLIC void cairotrm_options()
{
	char *s = NULL;
	char *font_setting = NULL;
	TBOOLEAN duplication = FALSE;
	TBOOLEAN set_font = FALSE, set_size = FALSE;
	TBOOLEAN set_capjoin = FALSE;
	TBOOLEAN set_standalone = FALSE, set_header = FALSE;

	char tmp_term_options[MAX_LINE_LEN+1] = "";

	/* Initialize terminal-dependent values */
	if ((strcmp(term->name, "pngcairo") == 0) || (strcmp(term->name, "kittycairo") == 0)) {
	    cairo_params = &cairopng_params;
	    cairo_params_default = &cairopng_params_default;
	} else if (strcmp(term->name, "epscairo") == 0) {
	    cairo_params = &cairoeps_params;
	    cairo_params_default = &cairoeps_params_default;
	}
#ifdef HAVE_WEBP
	else if (strcmp(term->name, "webp") == 0) {
	    cairo_params = &cairopng_params;
	    cairo_params_default = &cairopng_params_default;
	}
#endif
#ifdef PSLATEX_DRIVER
	else if (strcmp(term->name, "cairolatex") == 0) {
	    cairo_params = &cairolatex_params;
	    cairo_params_default = &cairolatex_params_default;
	    ps_params = &cairo_epslatex_params;
	}
#endif
	else {
	    cairo_params = &cairopdf_params;
	    cairo_params_default = &cairopdf_params_default;
	}

	/* Default to enhanced text mode */
	if (!almost_equals(c_token-1, "termopt$ion") && !ISCAIROLATEX) {
		cairo_params->enhanced = TRUE;
		term->flags |= TERM_ENHANCED_TEXT;
	}

	while (!END_OF_COMMAND) {
		FPRINTF((stderr, "processing token\n"));
		switch (lookup_table(&cairotrm_opts[0], c_token)) {
		case CAIROTRM_FONT:
			c_token++;
			if (!(s = try_to_get_string()))
				int_error(c_token,"font: expecting string");
			font_setting = gp_strdup(s);
			if (*s) {
				char *sep = strchr(s,',');
				if (sep) {
					sscanf(sep+1, "%f", &cairo_params->fontsize);
					*sep = '\0';
				}
				free(cairo_params->fontname);
				cairo_params->fontname = gp_strdup(s);
			}
			free(s);
			if (set_font) duplication=TRUE;
			set_font = TRUE;
			break;
		case CAIROTRM_ENHANCED:
			if (ISCAIROLATEX)
				int_error(c_token,
					  "extraneous argument in set terminal %s", term->name);
			c_token++;
			cairo_params->enhanced = TRUE;
			term->flags |= TERM_ENHANCED_TEXT;
			break;
		case CAIROTRM_NOENHANCED:
			if (ISCAIROLATEX)
				int_error(c_token,
					  "extraneous argument in set terminal %s", term->name);
			c_token++;
			cairo_params->enhanced = FALSE;
			term->flags &= ~TERM_ENHANCED_TEXT;
			break;
		case CAIROTRM_SIZE:
			c_token++;
			if (!strcmp(term->name,"pngcairo") || !strcmp(term->name, "kittycairo"))
			    cairo_params->explicit_units = parse_term_size(&cairo_params->width, &cairo_params->height, PIXELS);
#ifdef HAVE_WEBP
			else if (!strcmp(term->name,"webp"))
			    cairo_params->explicit_units = parse_term_size(&cairo_params->width, &cairo_params->height, PIXELS);
#endif
			else
			    cairo_params->explicit_units = parse_term_size(&cairo_params->width, &cairo_params->height, INCHES);
			if (set_size) duplication=TRUE;
			set_size = TRUE;
			break;
		case CAIROTRM_ROUNDED:
			c_token++;
			if (set_capjoin) duplication=TRUE;
			cairo_params->linecap = ROUNDED;
			set_capjoin = TRUE;
			break;
		case CAIROTRM_BUTT:
			c_token++;
			if (set_capjoin) duplication=TRUE;
			cairo_params->linecap = BUTT;
			set_capjoin = TRUE;
			break;
		case CAIROTRM_SQUARE:
			c_token++;
			if (set_capjoin) duplication=TRUE;
			cairo_params->linecap = SQUARE;
			set_capjoin = TRUE;
			break;
		case CAIROTRM_LINEWIDTH:
			c_token++;
			cairo_params->lw = real_expression();
			if (cairo_params->lw < 0.0)
			    cairo_params->lw = cairo_params_default->lw;
			break;
		case CAIROTRM_POINTSCALE:
			c_token++;
			cairo_params->ps = real_expression();
			if (cairo_params->ps < 0.0)
			    cairo_params->ps = 1.0;
			break;
		case CAIROTRM_DASHED:
		case CAIROTRM_SOLID:
			/* dashes always enabled in version 5 */
			c_token++;
			cairo_params->dashed = TRUE;
			break;
		case CAIROTRM_MONO:
			c_token++;
			cairo_params->mono = TRUE;
			term->flags |= TERM_MONOCHROME;
			break;
		case CAIROTRM_COLOR:
			c_token++;
			cairo_params->mono = FALSE;
			term->flags &= ~TERM_MONOCHROME;
			break;
		case CAIROTRM_DASHLENGTH:
			c_token++;
			cairo_params->dash_length = real_expression();
			if (cairo_params->dash_length < 0.0)
			    cairo_params->dash_length = cairo_params_default->dash_length;
			break;
		case CAIROTRM_FONTSCALE:
			c_token++;
			cairo_params->fontscale = END_OF_COMMAND ? -1 : real_expression();
			if (cairo_params->fontscale fontscale = cairo_params_default->fontscale;
			/* set_fontscale = TRUE; */
			break;
		case CAIROTRM_TRANSPARENT:
			c_token++;
			cairo_params->transparent = TRUE;
			break;
		case CAIROTRM_NOTRANSPARENT:
			c_token++;
			cairo_params->transparent = FALSE;
			break;
		case CAIROTRM_CROP:
			c_token++;
			if ((cairo_params->terminal == CAIROTERM_PNG) ||
			    (cairo_params->terminal == CAIROTERM_EPS))
			    cairo_params->crop = TRUE;
			break;
		case CAIROTRM_NOCROP:
			c_token++;
			if ((cairo_params->terminal == CAIROTERM_PNG) ||
			    (cairo_params->terminal == CAIROTERM_EPS))
			    cairo_params->crop = FALSE;
			break;
		case CAIROTRM_BACKGROUND:
			{
			int wxt_background;
			c_token++;
			wxt_background = parse_color_name();
			cairo_params->background.r = (double)((wxt_background >> 16) & 0xff) / 255.;
			cairo_params->background.g = (double)((wxt_background >>  8) & 0xff) / 255.;
			cairo_params->background.b = (double)( wxt_background        & 0xff) / 255.;
			cairo_params->transparent = FALSE;
			cairo_params->rgb_bkgnd = wxt_background & 0xffffff;
			break;
			}

#ifdef PSLATEX_DRIVER
		case CAIROLATEX_STANDALONE:
			if (!ISCAIROLATEX)
				int_error(c_token,
					  "extraneous argument in set terminal %s", term->name);
			ps_params->epslatex_standalone = TRUE;
			++c_token;
			if (set_standalone) duplication = TRUE;
			set_standalone = TRUE;
			break;
		case CAIROLATEX_INPUT:
			if (!ISCAIROLATEX)
				int_error(c_token,
					  "extraneous argument in set terminal %s", term->name);
			ps_params->epslatex_standalone = FALSE;
			++c_token;
			if (set_standalone) duplication = TRUE;
			set_standalone = TRUE;
			break;
		case CAIROLATEX_HEADER:
			if (!ISCAIROLATEX)
				int_error(c_token,
					  "extraneous argument in set terminal %s", term->name);
			++c_token;
			free(epslatex_header);
			/* Protect against int_error() bail from try_to_get_string() */
			epslatex_header = NULL;
			epslatex_header = try_to_get_string();
			if (!epslatex_header)
				int_error(c_token,"String containing header information expected");
			if (set_header) duplication = TRUE;
			set_header = TRUE;
			break;
		case CAIROLATEX_NOHEADER:
			if (!ISCAIROLATEX)
				int_error(c_token,
					  "extraneous argument in set terminal %s", term->name);
			free(epslatex_header);
			epslatex_header = NULL;
			if (set_header) duplication = TRUE;
			set_header = TRUE;
			++c_token;
			break;
		case CAIROLATEX_BLACKTEXT:
			if (!ISCAIROLATEX)
				int_error(c_token,
					  "extraneous argument in set terminal %s",term->name);
			ps_params->blacktext = TRUE;
			c_token++;
			break;
		case CAIROLATEX_COLORTEXT:
			if (!ISCAIROLATEX)
				int_error(c_token,
					  "extraneous argument in set terminal %s",term->name);
			ps_params->blacktext = FALSE;
			c_token++;
			break;
		case CAIROLATEX_EPS:
			if (!ISCAIROLATEX)
				int_error(c_token,
					  "extraneous argument in set terminal %s",term->name);
#ifdef HAVE_CAIROEPS
			cairo_params->output = CAIROLATEX_EPS;
#else
			int_error(c_token, "eps output not supported");
#endif
			c_token++;
			break;
		case CAIROLATEX_PDF:
			if (!ISCAIROLATEX)
				int_error(c_token,
					  "extraneous argument in set terminal %s",term->name);
			cairo_params->output = CAIROLATEX_PDF;
			c_token++;
			break;
		case CAIROLATEX_PNG:
			if (!ISCAIROLATEX)
				int_error(c_token,
					  "extraneous argument in set terminal %s",term->name);
			cairo_params->output = CAIROLATEX_PNG;
			++c_token;
			break;
		case CAIROLATEX_PNG_RESOLUTION:
			if (cairo_params->output != CAIROLATEX_PNG)
				int_error(c_token,
					  "extraneous argument in set terminal %s",term->name);
			++c_token;
			cairo_params->resolution = int_expression();
			if (cairo_params->resolution resolution = 300;
			break;
#endif /* PSLATEX_DRIVER */

		case CAIROTRM_OTHER:
			/* Ignore irrelevant keywords used by other png/pdf drivers */
			if (almost_equals(c_token,"true$color")
			||  almost_equals(c_token,"inter$lace")
			||  almost_equals(c_token,"nointer$lace")) {
			    c_token++;
			    break;
			}
#ifdef HAVE_WEBP
			if (strcmp(term->name, "webp") == 0) {
			    int save_token = c_token;
			    WEBP_options(0);
			    if (save_token != c_token)
				break;
			}
#endif
#ifdef HAVE_KITTY_TERM
			if (strncmp(term->name, "kitty", 5) == 0) {
			    if (equals(c_token, "animate") || equals(c_token, "anchor")) {
				c_token++;
				cairo_params->anchor = TRUE;
				break;
			    }
			    if (equals(c_token, "scroll")) {
				c_token++;
				cairo_params->anchor = FALSE;
				break;
			    }
			}
#endif

		default:
			int_error(c_token, "unrecognized terminal option");
			break;
		}

		if (duplication)
			int_error(c_token-1, "Duplicated or contradicting arguments in cairo terminal options.");
	}

#if 0
	/* Copy terminal-dependent values to the generic equivalent */
	cairo_params->width = cairo_params_default->width;
	cairo_params->height = cairo_params_default->height;
	cairo_params->base_linewidth = cairo_params_default->base_linewidth;
#endif

#ifdef PSLATEX_DRIVER
	if (ISCAIROLATEX) {
		const char * output = "";
		switch (cairo_params->output) {
		default:
		case CAIROLATEX_PDF:
			output = "pdf";
			break;
		case CAIROLATEX_EPS:
			output = "eps";
			break;
		case CAIROLATEX_PNG:
			output = "png";
			break;
		}
		sprintf(tmp_term_options, " %s %s", output,
			ps_params->epslatex_standalone ? "standalone" : "input");
		strcat(term_options, tmp_term_options);
		if (epslatex_header)
			sprintf(tmp_term_options, " header \"%s\"", epslatex_header);
		else
			sprintf(tmp_term_options, " noheader");
		strcat(term_options, tmp_term_options);
		sprintf(tmp_term_options, " %s", ps_params->blacktext ? "blacktext" : "colortext");
		strcat(term_options, tmp_term_options);
	}
#endif

	/* Save options back into options string in normalized format */
	if (cairo_params->transparent)
		strncat(term_options, ISCAIROLATEX ? " nobackground" : " transparent",
			sizeof(term_options) - strlen(term_options)-1);
	else {
		sprintf(tmp_term_options, " background \"#%02x%02x%02x\"",
			(int)(255 * cairo_params->background.r),
			(int)(255 * cairo_params->background.g),
			(int)(255 * cairo_params->background.b));
		strcat(term_options, tmp_term_options);
	}

	if (cairo_params->crop)
		strncat(term_options, " crop", sizeof(term_options)-strlen(term_options)-1);

	if (strncmp(term->name,"kitty",5) == 0)
	    strncat(term_options, cairo_params->anchor ? " anchor" : " scroll",
		sizeof(term_options)-strlen(term_options)-1);

	strncat(term_options, cairo_params->enhanced ? " enhanced" : " noenhanced",
		sizeof(term_options)-strlen(term_options)-1);

	if (set_font) {
		snprintf(tmp_term_options, sizeof(tmp_term_options), " font \"%s\"", font_setting);
		free(font_setting);
		strncat(term_options, tmp_term_options, sizeof(term_options)-strlen(term_options)-1);
	}

	/* if (set_fontscale) */
	{
		snprintf(tmp_term_options, sizeof(tmp_term_options), " fontscale %.1f", cairo_params->fontscale);
		strncat(term_options, tmp_term_options, sizeof(term_options)-strlen(term_options)-1);
	}

	if (cairo_params->mono)
		strncat(term_options, " monochrome", sizeof(term_options)-strlen(term_options)-1);

	if (1 || set_size) {
		if (cairo_params->explicit_units == CM)
			snprintf(tmp_term_options,
				sizeof(tmp_term_options),
				" size %.2fcm, %.2fcm ",
				2.54*cairo_params->width/72., 2.54*cairo_params->height/72.);
		else if (cairo_params->explicit_units == PIXELS)
			snprintf(tmp_term_options,
				sizeof(tmp_term_options),
				" size %d, %d ",
				(int)cairo_params->width, (int)cairo_params->height);
		else
			snprintf(tmp_term_options,
				sizeof(tmp_term_options),
				" size %.2fin, %.2fin ",
				cairo_params->width/72., cairo_params->height/72.);
		strncat(term_options, tmp_term_options, sizeof(term_options)-strlen(term_options)-1);
	}

	if (set_capjoin) {
		strncat(term_options,
			cairo_params->linecap == ROUNDED ? " rounded"
			: cairo_params->linecap == BUTT ? " butt"
			: " square",
			sizeof(term_options)-strlen(term_options)-1);
	}

	if (cairo_params->lw != cairo_params_default->lw) {
		snprintf(tmp_term_options,sizeof(tmp_term_options), " linewidth %g", cairo_params->lw);
		strncat(term_options, tmp_term_options, sizeof(term_options)-strlen(term_options)-1);
	}

	if (cairo_params->ps != 1.0) {
		snprintf(tmp_term_options,sizeof(tmp_term_options), " pointscale %g", cairo_params->ps);
		strncat(term_options, tmp_term_options, sizeof(term_options)-strlen(term_options)-1);
	}


	if (cairo_params->dash_length != cairo_params_default->dash_length) {
		snprintf(tmp_term_options,sizeof(tmp_term_options), " dashlength %g", cairo_params->dash_length);
		strncat(term_options, tmp_term_options, sizeof(term_options)-strlen(term_options)-1);
	}

	/* sync settings with ps_params for latex terminal */
#ifdef PSLATEX_DRIVER
	if (ISCAIROLATEX) {
		ps_params->color = !cairo_params->mono;
		ps_params->font[sizeof(ps_params->font) - 1] = '\0';
		if (!cairo_params->fontname)
			ps_params->font[0] = '\0';
		else
			strncpy(ps_params->font, cairo_params->fontname, sizeof(ps_params->font) - 1);
		ps_params->fontsize = cairo_params->fontsize;
		ps_params->fontscale = cairo_params->fontscale;
		if (cairo_params->transparent) {
			ps_params->background.r = -1;
			ps_params->background.g = -1;
			ps_params->background.b = -1;
		} else {
			ps_params->background.r = cairo_params->background.r;
			ps_params->background.g = cairo_params->background.g;
			ps_params->background.b = cairo_params->background.b;
		}
	}
#endif

#ifdef HAVE_WEBP
	/* Add webp-specific options to the terminal option string */
	if (strcmp(term->name, "webp") == 0)
	    WEBP_options(1);
#endif
}

#ifdef HAVE_CAIROEPS
/*
 * Helper routine for eps output
 */
static void add_BoundingBox(cairo_surface_t *surface)
{
    /* Early cairo versions did not allow an explicit bounding box */
    #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,11,1)
    char bb[100];
	sprintf(bb, "%%%%BoundingBox: 0 0 %i %i", plot.device_xmax, plot.device_ymax);
	cairo_ps_surface_dsc_comment(surface, bb);
	cairo_ps_surface_dsc_begin_page_setup(surface);
	sprintf(bb, "%%%%PageBoundingBox: 0 0 %i %i", plot.device_xmax, plot.device_ymax);
	cairo_ps_surface_dsc_comment(surface, bb);
    #endif /* CAIRO_VERSION >= 1.11.1 */
}
#endif /* HAVE_CAIROEPS */

/* "Called once, when the device is first selected."
 * Is the 'main' function of the terminal. */
void cairotrm_init()
{
	cairo_surface_t *surface = NULL;

	FPRINTF((stderr,"Init\n"));

	/* do a sanity check for once */
	if (strcmp(term->name, "epscairo") && strcmp(term->name, "cairolatex") &&
	    strcmp(term->name, "pdfcairo") && strcmp(term->name, "pngcairo") &&
            strcmp(term->name, "kittycairo"))
		int_error(c_token,"Unrecognized cairo terminal");

	/* cairolatex requires a file */
	if (ISCAIROLATEX && !outstr)
	    os_error(c_token, "cairolatex terminal cannot write to standard output");

	/* We no longer rely on this having been done in cairotrm_reset() */
	if (plot.cr)
	    cairo_destroy(plot.cr);

	/* initialisations */
	gp_cairo_initialize_plot(&plot);
	plot.device_xmax = (double) cairo_params->width;
	plot.device_ymax = (double) cairo_params->height;
	plot.dashlength = cairo_params->dash_length;

	if (!strcmp(term->name,"pdfcairo")) {
	    #ifdef _WIN32
		/* Redirection to a printer on Windows requires the use of gpoutfile
		 * via the cairostream_write callback.
		 */
		    surface = cairo_pdf_surface_create_for_stream(
			(cairo_write_func_t)cairostream_write, cairostream_error,
				plot.device_xmax /*double width_in_points*/,
				plot.device_ymax /*double height_in_points*/);
	    #else
		/* Output can either be a file or stdout */
		if (outstr) {
		    surface = cairo_pdf_surface_create(outstr,
				plot.device_xmax, plot.device_ymax);
		} else {
		    surface = cairo_pdf_surface_create_for_stream(
			(cairo_write_func_t)cairostream_write, cairostream_error,
				plot.device_xmax, plot.device_ymax);
		}
	    #endif /* _WIN32 */
		/* it is up to the pdf viewer to do the hinting */
		plot.hinting = 0;
		/* Cairo at least through version 16 fails to handle OPERATOR_SATURATE
		 * when applied to pdf surfaces;  it degrades the rendering of all text.
		 * Unfortunately, without it there may be visible artifacts at the
		 * boundary between filled polygons (viewer-dependent).
		 */
		plot.polygons_saturate = FALSE;
		/* Empirical correction to make pdf output look more like wxt and png */
		plot.dashlength /= 2;
	} else if (!strcmp(term->name,"pngcairo") || !strcmp(term->name, "kittycairo")) {
		surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32,
				plot.device_xmax /*double width_in_points*/,
				plot.device_ymax /*double height_in_points*/);
		/* png is bitmapped, let's do the full hinting */
		plot.hinting = 100;
		plot.polygons_saturate = TRUE;
	}
	#ifdef HAVE_CAIROEPS
	else if (!strcmp(term->name,"epscairo")) {
		/* Output can either be a file or stdout */
		if (!outstr) {
		    surface = cairo_ps_surface_create_for_stream(
			(cairo_write_func_t)cairostream_write, cairostream_error,
				plot.device_xmax /*double width_in_points*/,
				plot.device_ymax /*double height_in_points*/);
		} else {
		    surface = cairo_ps_surface_create(outstr,
				plot.device_xmax /*double width_in_points*/,
				plot.device_ymax /*double height_in_points*/);
		}
		cairo_ps_surface_set_eps(surface, TRUE);
		if (!cairo_params->crop)
			add_BoundingBox(surface);
		/* OPERATOR_SATURATE is OK for epscairo because
		 * text is handled by PostScript rather than cairo/pango.
		 */
		plot.polygons_saturate = TRUE;
		plot.hinting = 0;
		/* Empirical correction to make eps output look more like wxt and png */
		plot.dashlength /= 2;
	}
	#endif /* HAVE_CAIROEPS */

	#ifdef PSLATEX_DRIVER
	else if (ISCAIROLATEX) {
		/* Output can only go to a stream */
		switch (cairo_params->output) {
		default:
		case CAIROLATEX_PDF:
			EPSLATEX_reopen_output("pdf");
			surface = cairo_pdf_surface_create_for_stream(
					(cairo_write_func_t)cairostream_write, cairostream_error,
					plot.device_xmax /*double width_in_points*/,
					plot.device_ymax /*double height_in_points*/);
			break;
		case CAIROLATEX_PNG:
			EPSLATEX_reopen_output("png");
			/* We manually scale up to 300 dpi instead of the default 72 dpi */
			plot.upsampling_rate = cairo_params->resolution / 72.;
			surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
					(int)floor(plot.device_xmax * plot.upsampling_rate),
					(int)floor(plot.device_ymax * plot.upsampling_rate));
			break;
		#ifdef HAVE_CAIROEPS
		case CAIROLATEX_EPS:
			EPSLATEX_reopen_output("eps");
			surface = cairo_ps_surface_create_for_stream(
				    (cairo_write_func_t)cairostream_write, cairostream_error,
				    plot.device_xmax /*double width_in_points*/,
				    plot.device_ymax /*double height_in_points*/);
			cairo_ps_surface_set_eps(surface, TRUE);
			add_BoundingBox(surface);
			break;
		#endif /* HAVE_CAIROEPS */
		}

		switch (cairo_params->output) {
		case CAIROLATEX_PNG:
			/* png is bitmapped, let's do the full hinting */
			plot.hinting = 100;
			plot.polygons_saturate = TRUE;
			break;
		default:
			/* it is up to the pdf viewer to do the hinting */
			plot.hinting = 0;
			/* OPERATOR_SATURATE is OK for cairolatex because
			 * text is generated by LaTeX rather than cairo/pango.
			 */
			plot.polygons_saturate = TRUE;
			/* Empirical correction to make pdf output look more like wxt and png */
			plot.dashlength /= 2;
			break;
		}
	}
	#endif /* PSLATEX_DRIVER */

	plot.cr = cairo_create(surface);
	cairo_surface_destroy( surface );

	FPRINTF((stderr,"status = %s\n",cairo_status_to_string(cairo_status(plot.cr))));
	FPRINTF((stderr,"Init finished \n"));
}

/* "Called just before a plot is going to be displayed."
 * Should clear the terminal. */
void cairotrm_graphics()
{
	/* Initialize background */
	plot.background.r = cairo_params->background.r;
	plot.background.g = cairo_params->background.g;
	plot.background.b = cairo_params->background.b;
	gp_cairo_set_background(cairo_params->background);
	if (ISCAIROLATEX || cairo_params->transparent)
		gp_cairo_clear_background(&plot);
	else
		gp_cairo_solid_background(&plot);

	/* update the window scale factor first, cairo needs it */
	plot.xscale = 1.0;
	plot.yscale = 1.0;

	/* We manually scale up the PNG for higher pixel density */
	if (ISCAIROLATEX && cairo_params->output == CAIROLATEX_PNG) {
		plot.xscale = plot.upsampling_rate;
		plot.yscale = plot.upsampling_rate;
	}

	/* update graphics state properties */
	plot.linecap = cairo_params->linecap;

	FPRINTF((stderr,"Graphics1\n"));

	/* set the transformation matrix of the context, and other details */
	/* depends on plot.xscale and plot.yscale */
	gp_cairo_initialize_context(&plot);

	/* set or refresh terminal size according to the window size */
	/* oversampling_scale is updated in gp_cairo_initialize_context */
	plot.xmax = (unsigned int) plot.device_xmax*plot.oversampling_scale;
	plot.ymax = (unsigned int) plot.device_ymax*plot.oversampling_scale;
	/* initialize encoding */
	plot.encoding = encoding;

	/* Adjust for the mismatch of floating point coordinate range 0->max	*/
	/* and integer terminal pixel coordinates [0:max-1].			*/
	term->xmax = (plot.device_xmax - 1) * plot.oversampling_scale;
	term->ymax = (plot.device_ymax - 1) * plot.oversampling_scale;
	term->tscale = plot.oversampling_scale;

#ifdef _WIN32
	/* On Windows, always explicitly set the resolution to 96dpi to avoid
       applying the "text scaling" factor. */
	gp_cairo_set_resolution(96);
#endif

	/* set font details (h_char, v_char) according to settings */
	cairotrm_set_font("");

	term->v_tic = (unsigned int) (term->v_char/2.5);
	term->h_tic = (unsigned int) (term->v_char/2.5);

#ifdef PSLATEX_DRIVER
	/* Init latex output, requires terminal size */
	if (ISCAIROLATEX)
		EPSLATEX_common_init();
#endif

	#if CAIRO_VERSION < CAIRO_VERSION_ENCODE(1,11,1)
	/* Put "invisible" points in two corners to enforce bounding box. */
	if ((ISCAIROLATEX) || ((cairo_params->terminal == CAIROTERM_EPS) && !cairo_params->crop)) {
		cairo_set_line_width(plot.cr, 1);
		cairo_set_source_rgb(plot.cr, cairo_params->background.r,
				cairo_params->background.g, cairo_params->background.b);
		cairo_move_to(plot.cr, 0, 0);
		cairo_line_to(plot.cr, 1, 0);
		cairo_move_to(plot.cr, plot.xmax - 1, plot.ymax);
		cairo_line_to(plot.cr, plot.xmax, plot.ymax);
		cairo_stroke(plot.cr);
	}
	#endif

	FPRINTF((stderr,"Graphics xmax %d ymax %d v_char %d h_char %d\n",
		term->xmax, term->ymax, term->v_char, term->h_char));
}


/* cairo mechanism to allow writing to an output stream */
cairo_status_t
cairostream_write(void *closure, unsigned char *data, unsigned int length)
{
	/* in case of a cairolatex terminal, output is redirected to a secondary file */
	if (length != fwrite(data, 1, length, (ISCAIROLATEX) ? gppsfile : gpoutfile))
		return CAIRO_STATUS_WRITE_ERROR;
	return CAIRO_STATUS_SUCCESS;
}

void
cairopng_write_cropped_image(cairo_surface_t *surface)
{
  unsigned char *data = cairo_image_surface_get_data(surface);
  int width = cairo_image_surface_get_width(surface);
  int height = cairo_image_surface_get_height(surface);
  int stride = cairo_image_surface_get_stride(surface);
  int  i, j, x1 = 0, y1 = 0, x2 = width, y2 = height;

  guint32 *row;
  guint32 BG = (cairo_params->transparent)
		? 0x0
		: cairo_params->rgb_bkgnd | 0xff000000;

  /* Row-wise, top-down iteration */
  for (i = 0; i < height; i++) {
    row = (guint32 *) (data + i * stride);
    for (j = 0; j < width; j++) {
      if (row[j] != BG) {
	y1 = i;
	goto found_y1;
      }
    }
  }
 found_y1:
  /* Row-wise, bottom-up iteration */
  for (i = height - 1; i >= y1; i--) {
    row = (guint32 *)(data + i * stride);
    for (j = 0; j < width; j++) {
      if (row[j] != BG) {
	y2 = i;
	goto found_y2;
      }
    }
  }
 found_y2:
  /* Column-wise, left-to-right iteration */
  for (j = 0; j < width; j++) {
    for (i = y1; i = x1; j--) {
    for (i = y1; i name, "pngcairo") == 0 ||
		(strcmp(term->name, "cairolatex") == 0 &&
		cairo_params->output == CAIROLATEX_PNG)) {
		cairo_surface_t *surface = cairo_get_target(plot.cr);
		if (cairo_params->crop) {
			cairopng_write_cropped_image(surface);
		} else {
			cairo_surface_write_to_png_stream(surface,
				(cairo_write_func_t)cairostream_write, cairostream_error);
		}
#ifdef HAVE_KITTY_TERM
        } else if (strcmp(term->name, "kittycairo") == 0) {
          base64s *b64;
          cairo_surface_t *surface = cairo_get_target(plot.cr);
          /* TODO: crop */
	  /* Draw starting at top left of screen */
	  if (cairo_params->anchor)
		fprintf(gpoutfile,  "\033[H");
          kitty_init(KITTY_FORMAT_PNG);
          b64 = gp_alloc(sizeof(base64s), "base64s");
          init_base64_state_data(b64, kitty_writechar, NULL);
          cairo_surface_write_to_png_stream(surface, cairo_write_base64_callback, b64);
          piecemeal_write_base64_data_finish(b64);
          free(b64);
          kitty_flush(FALSE);
          fputc('\n', gpoutfile);
#endif
        }

	FPRINTF((stderr,"status = %s\n",cairo_status_to_string(cairo_status(plot.cr))));

	FPRINTF((stderr,"Text finished\n"));
}

/* sent when gnuplot exits and when the terminal or the output change.*/
void cairotrm_reset()
{
	if (plot.cr)
		cairo_destroy(plot.cr);
	plot.cr = NULL;

#ifdef PSLATEX_DRIVER
	/* finish latex output */
	if (ISCAIROLATEX)
		PSLATEX_reset();
#endif

	FPRINTF((stderr,"cairotrm_reset\n"));
}

void cairotrm_move(unsigned int x, unsigned int y)
{
	gp_cairo_move(&plot, x, term->ymax - y);
}

void cairotrm_vector(unsigned int x, unsigned int y)
{
	gp_cairo_vector(&plot, x, term->ymax - y);
}

void cairotrm_put_text(unsigned int x, unsigned int y, const char * string)
{
	if (!string || !strlen(string))
		return;

	/* if ignore_enhanced_text is set, draw with the normal routine.
	 * This is meant to avoid enhanced syntax when the enhanced mode is on */
	if (ignore_enhanced_text || !cairo_params->enhanced) {
		gp_cairo_draw_text(&plot, x, term->ymax - y, string, NULL, NULL);
		return;
	}

	/* If there are no mark-up characters we can use the normal routine */
	if (!strpbrk(string, "{}^_@&~") && !contains_unicode(string)) {
		gp_cairo_draw_text(&plot, x, term->ymax - y, string, NULL, NULL);
		return;
	}

	/* Uses enhanced_recursion() to analyse the string to print.
	 * enhanced_recursion() calls _enhanced_open() to initialize the text drawing,
	 * then it calls _enhanced_writec() which buffers the characters to draw,
	 * and finally _enhanced_flush() to draw the buffer with the correct justification.
	 */

	gp_cairo_enhanced_init(&plot, strlen(string));

	/* set up the global variables needed by enhanced_recursion() */
	enhanced_fontscale = cairo_params->fontscale;
	strncpy(enhanced_escape_format, "%c", sizeof(enhanced_escape_format));

	/* Set the recursion going. We say to keep going until a closing brace,
	 * but we don't really expect to find one. If the return value is not
	 * the nul-terminator of the string, that can only mean that we did find
	 * an unmatched closing brace in the string. We increment past it (else
	 * we get stuck in an infinite loop) and try again.
	 */

	while (*(string = enhanced_recursion((char*)string, TRUE,
			cairo_enhanced_fontname,
			plot.fontsize,
			0.0, TRUE, TRUE, 0))) {
		cairotrm_enhanced_flush();

		/* we can only get here if *str == '}' */
		enh_err_check(string);

		if (!*++string)
			break; /* end of string */
		/* else carry on and process the rest of the string */
	}

	/* I still don't understand why this is needed */
	gp_cairo_clear_bold_font(&plot);

	/* finish */
	gp_cairo_enhanced_finish(&plot, x, term->ymax - y);
	return;

}

void cairotrm_enhanced_flush()
{
	gp_cairo_enhanced_flush(&plot);
}

void cairotrm_enhanced_writec(int c)
{
	gp_cairo_enhanced_writec(&plot, c);
}

void cairotrm_enhanced_open(char* fontname, double fontsize, double base, TBOOLEAN widthflag, TBOOLEAN showflag, int overprint)
{
	gp_cairo_enhanced_open(&plot, fontname, fontsize,
				base, widthflag, showflag, overprint);
}

void cairotrm_linetype(int lt)
{
	gp_cairo_set_linetype(&plot, lt);

	/* Version 5: always set solid lines at this point.  If a dashed */
	/* line is wanted there will be a later call to term->dashtype() */
	gp_cairo_set_linestyle(&plot,  GP_CAIRO_SOLID);

	if (cairo_params->mono && lt >= -1)
		gp_cairo_set_color(&plot, gp_cairo_linetype2color( -1 ), 0.0);
	else
		gp_cairo_set_color(&plot, gp_cairo_linetype2color( lt ), 0.0);
}


/* - fonts are selected as strings "name,size".
 * - _set_font("") restores the terminal's default font.*/
int cairotrm_set_font (const char *font)
{
	char *fontname = NULL;
	float fontsize = 0;

	if (font && (*font)) {
		int sep = strcspn(font,",");
		fontname = strdup(font);
		if (font[sep] == ',') {
			sscanf(&(font[sep+1]), "%f", &fontsize);
			fontname[sep] = '\0';
		}
	} else {
		fontname = strdup("");
	}

	if ( strlen(fontname) == 0 ) {
		free(fontname);
		if ( !cairo_params->fontname || strlen(cairo_params->fontname) == 0 )
			fontname = gp_strdup(CAIROTRM_DEFAULT_FONTNAME);
		else
			fontname = gp_strdup(cairo_params->fontname);
	}

	if ( fontsize == 0 ) {
		if ( cairo_params->fontsize == 0 )
			fontsize = cairo_params_default->fontsize;
		else
			fontsize = cairo_params->fontsize;
	}

	/* Reset the term variables (hchar, vchar, h_tic, v_tic).
	 * They may be taken into account in next plot commands */
	gp_cairo_set_font(&plot, fontname, fontsize * cairo_params->fontscale);
	gp_cairo_set_termvar(&plot, &(term->v_char), &(term->h_char));

	/* Enhanced text processing needs to know the new font also */
	if (*fontname) {
		free(cairo_enhanced_fontname);
		cairo_enhanced_fontname = strdup(fontname);
	}
	free(fontname);

	/* the returned int is not used anywhere */
	return 1;
}


int cairotrm_justify_text(enum JUSTIFY mode)
{
	gp_cairo_set_justify(&plot,mode);

	return 1; /* we can justify */
}

void cairotrm_point(unsigned int x, unsigned int y, int pointstyle)
{
	gp_cairo_draw_point(&plot, x, term->ymax - y, pointstyle);
}

void cairotrm_pointsize(double ptsize)
{
	ptsize = (ptsize < 0) ? cairo_params->ps : cairo_params->ps * ptsize;
	gp_cairo_set_pointsize(&plot, ptsize);
}

void cairotrm_linewidth(double lw)
{
	lw *= cairo_params->lw * cairo_params->base_linewidth;
	gp_cairo_set_linewidth(&plot, lw);
}

int cairotrm_text_angle(float angle)
{
	/* a double is needed to compute cos, sin, etc. */
	gp_cairo_set_textangle(&plot, angle);

	return 1; /* 1 means we can rotate */
}

void cairotrm_fillbox(int style, unsigned int x, unsigned int y, unsigned int width, unsigned int height)
{
	gp_cairo_draw_fillbox(&plot, x, term->ymax - y,
				width, height,
				style);
}

int cairotrm_make_palette(t_sm_palette * palette)
{
	/* we can do continuous colors */
	return 0;
}

void cairotrm_set_color(t_colorspec *colorspec)
{
	rgb_color rgb1;
	double alpha = 0.0;

	if (colorspec->type == TC_LT) {
		rgb1 = gp_cairo_linetype2color(colorspec->lt);
	} else if (colorspec->type == TC_FRAC && cairo_params->mono) {
		int save_colorMode = sm_palette.colorMode;
		sm_palette.colorMode = SMPAL_COLOR_MODE_GRAY;
		rgb1maxcolors_from_gray( colorspec->value, &rgb1 );
		sm_palette.colorMode = save_colorMode;
	} else if (colorspec->type == TC_FRAC) {
		rgb1maxcolors_from_gray( colorspec->value, &rgb1 );
	} else if (colorspec->type == TC_RGB) {
		rgb1.r = (double) ((colorspec->lt >> 16) & 0xff)/255;
		rgb1.g = (double) ((colorspec->lt >> 8) & 0xff)/255;
		rgb1.b = (double) ((colorspec->lt) & 0xff)/255;
		alpha = (double) ((colorspec->lt >> 24) & 0xff)/255;
	} else return;

	gp_cairo_set_color(&plot, rgb1, alpha);
#if PSLATEX_DRIVER
	/* Used by EPSLATEX_boxed_text */
	PSLATEX_opacity = 1.0 - alpha;
#endif
}


/* here we send the polygon command */
void cairotrm_filled_polygon(int n, gpiPoint *corners)
{
	gpiPoint *corners_copy;

	if (n 

Web Proxy Viewer  |  New URL  |  Original Page