The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
/*
 * $Id: gif.trm,v 1.40 2002/08/27 21:22:19 sfeam Exp $
 */

/* GNUPLOT -- gif.trm */

/*[
 * Copyright 1998
 *
 * 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:
 *  GD GIF library 1.2 & 1.3
 *
 * To Use:
 *
 * set terminal gif ?options ...?
 *
 * Where an option is:
 *
 * transparent - generate transparent GIFs.  The first color will
 * be the transparent one.
 *
 * interlace - generate interlaced GIFs.
 *
 * size (in pixels)
 *
 * font (tiny,small,medium,large,giant)
 *
 * xrrggbb - sets the next color.  x is the literal character 'x',
 * rrggbb are the red green and blue components in hex.  For example
 * x00ff00 is green.  The background color is set first, then the
 * color borders, then the X & Y axis, then the plotting colors.
 * (The wierd color spec is in order to get around limitations
 * in gnuplot's scanner.)
 *
 * This driver is modeled after the PBM driver pbm.trm.
 *
 * AUTHORS
 *  Sam Shen <sls@mh1.lbl.gov>
 *  Alex Woo <woo@playfair.stanford.edu>
 *
 * CONTRIBUTORS
 *  Alfred Reibenschuh <alfred.reibenschuh@it-austria.com> or <fredo@blackbox.at>
 *  Ben Laurie <ben@algroup.co.uk>
 *
 * send your comments or suggestions to:
 *  info-gnuplot@cs.dartmouth.edu
 * 
 * This version outputs either color or monochrome GIFs.  The default
 * is 640x480 pixels.  
 *
 * link with -Lterm/gd -lgd if your directory structure is gnuplot/term/gd
 *
 * gd is not distributed with gnuplot, because of the UNISYS license thing.
 *
 * find out about gd from http://www.boutell.com/gd/
 *
 * We recommend to use gd library version 1.3 or 1.4 because it uses
 * Run Length Encoding (RLE) instead of LZW compression. LZW compression
 * is licensed by UNISYS.
 *
 * Gd library versions before 1.3, and gd library 1.5 are subject to
 * the Unisys license. Use at your own risk. From version 1.6 on, gd
 * library creates png files instead of gif.
 *
 * Petr Mikulik, Jan 1999: terminal entries for PM3D functionality
 */

/*
 * This definition is triggered by the configuration option --with-gif=png
 * It provides backwards compatibility with existing scripts that used the
 * old gif driver and libgd versions <1.6 by substituting creation of PNG 
 * images in response to * 'set term gif' using the PNG support in libgd
 * versions >= 1.8
 * Ethan A Merritt - Nov 2001
 */
#ifdef PNG_FOR_GIF
#define gdImageGif gdImagePng
#endif


#include "driver.h"

#ifdef TERM_REGISTER
register_term(gif)
#endif

#ifdef TERM_PROTO
TERM_PUBLIC void GIF_options __PROTO((void));
TERM_PUBLIC void GIF_init __PROTO((void));
TERM_PUBLIC void GIF_graphics __PROTO((void));
TERM_PUBLIC void GIF_text __PROTO((void));
TERM_PUBLIC void GIF_linetype __PROTO((int linetype));
TERM_PUBLIC void GIF_move __PROTO((unsigned int x, unsigned int y));
TERM_PUBLIC void GIF_vector __PROTO((unsigned int x, unsigned int y));
TERM_PUBLIC void GIF_put_text __PROTO((unsigned int x, unsigned int y, const char str[]));
TERM_PUBLIC int GIF_text_angle __PROTO((int ang));
TERM_PUBLIC void GIF_reset __PROTO((void));
TERM_PUBLIC int GIF_set_font __PROTO((const char *fontname));
TERM_PUBLIC void GIF_boxfill __PROTO((int style, unsigned int x, unsigned int y, unsigned int w, unsigned int h));
#ifdef PM3D
TERM_PUBLIC int GIF_make_palette (t_sm_palette *);
/* TERM_PUBLIC void GIF_previous_palette (void); */
TERM_PUBLIC void GIF_set_color (double);
TERM_PUBLIC void GIF_filled_polygon (int, gpiPoint *);
#endif

#include "gd.h"

extern gdFontPtr gdFontSmall;	/* 6x12 */
extern gdFontPtr gdFontLarge;	/* 8x16 */
extern gdFontPtr gdFontMediumBold;	/* 7x13 */
extern gdFontPtr gdFontGiant;  /* 9x15 */
extern gdFontPtr gdFontTiny;  /* 5x8 */


#define GREG_XMAX 640
#define GREG_YMAX 480


static int GIF_XMAX = GREG_XMAX;
static int GIF_YMAX = GREG_YMAX;


#define GIF_FONT_SMALL 1
#ifdef GIF_FONT_SMALL
# define gdfont gdFontSmall
# define GIF_VCHAR 12
# define GIF_HCHAR 6
#else
# define gdfont gdFontMediumBold
# define GIF_VCHAR 13
# define GIF_HCHAR 7
#endif

static gdFontPtr GIF_font;

#define GIF_VTIC (GREG_YMAX/100)
#define GIF_HTIC (GREG_XMAX/150)

#define GIF_MAX_COLORS 256
#define GOT_NEXT_PROTO
#endif

#ifndef TERM_PROTO_ONLY
#ifdef TERM_BODY

static struct {
    gdImagePtr image;
    gdFontPtr font;
    unsigned int x, y;
    int height;
    int charh, charw;
    int color;
    int n_colors;
    int color_table[GIF_MAX_COLORS];
    int rgb_table[GIF_MAX_COLORS];
    int angle;
    int flags;
    int linetype;
} gif_state;

#define GIF_USE_TRANSPARENT 1
#define GIF_USE_INTERLACE   2

enum GIF_id {
    GIF_TRANSPARENT, GIF_INTERLACE,
    /* FOnt size */
    GIF_TINY, GIF_SMALL, GIF_MEDIUM, GIF_LARGE, GIF_GIANT,
    GIF_SIZE,
    GIF_OTHER
};

static struct gen_table GIF_opts[] =
{
    { "tr$ansparent", GIF_TRANSPARENT },
    { "i$nterlace", GIF_INTERLACE },
    { "ti$ny", GIF_TINY },
    { "s$mall", GIF_SMALL },
    { "m$edium", GIF_MEDIUM },
    { "l$arge", GIF_LARGE },
    { "g$iant", GIF_GIANT },
    { "si$ze", GIF_SIZE },
    { NULL, GIF_OTHER }
};

/*
 * _options()  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
GIF_options()
{
    struct value s;
    int gif_font, i;
    char *string;
    unsigned long color;
    
    term_options[0] = NUL;
    gif_state.n_colors = 0;
    gif_state.flags = 0;
    gif_font = 1;
    GIF_font = gdfont;

    while (!END_OF_COMMAND) {
	switch(lookup_table(&GIF_opts[0],c_token)) {
	case GIF_TRANSPARENT:
	    gif_state.flags |= GIF_USE_TRANSPARENT;
	    ++c_token;
	    break;
	case GIF_INTERLACE:
	    gif_state.flags |= GIF_USE_INTERLACE;
	    ++c_token;
	    break;
	case GIF_TINY:
	    GIF_font=gdFontTiny;
	    gif_font = 0;
	    term->v_char = (unsigned int)(8);
	    term->h_char = (unsigned int)(5);
	    ++c_token;
	case GIF_SMALL:
	    GIF_font = gdFontSmall;
	    gif_font = 1;
	    term->v_char = (unsigned int) (12);
	    term->h_char = (unsigned int) (6);
	    ++c_token;
	    break;
	case GIF_MEDIUM:
	    GIF_font = gdFontMediumBold;
	    gif_font = 2;
	    term->v_char = (unsigned int) (13);
	    term->h_char = (unsigned int) (7);
	    ++c_token;
	    break;
	case GIF_LARGE:
	    GIF_font = gdFontLarge;
	    gif_font = 3;
	    term->v_char = (unsigned int) (16);
	    term->h_char = (unsigned int) (8);
	    ++c_token;
	    break;
	case GIF_GIANT:
	    GIF_font=gdFontGiant;
	    gif_font = 4;
	    term->v_char = (unsigned int)(15);
	    term->h_char = (unsigned int)(9);
	    ++c_token;
	    break;
	case GIF_SIZE:
	    c_token++;
	    if (END_OF_COMMAND) {
		GIF_XMAX = GREG_XMAX;
		GIF_YMAX = GREG_YMAX;
		term->v_tic = GIF_YMAX / 80;
		term->h_tic = GIF_XMAX / 80;
	    } else {
		GIF_XMAX = real(const_express(&s));
		if (equals(c_token, ",")) {
		    c_token++;
		    GIF_YMAX = real(const_express(&s));
		    term->v_tic = GIF_YMAX / 80;
		    term->h_tic = GIF_XMAX / 80;
		    term->ymax = GIF_YMAX;
		    term->xmax = GIF_XMAX;
		}
	    }
	    break;
	case GIF_OTHER:
	default:
	    /* not "size" */
	    string = input_line + token[c_token].start_index;

	    if (sscanf(string, "x%lx", &color) != 1) {
		int_error(c_token, "invalid color spec, must be xRRGGBB");
	    } else if (gif_state.n_colors == GIF_MAX_COLORS) {
		int_warn(c_token, "too many colors, ingoring");
		++c_token;
	    } else {
		gif_state.rgb_table[gif_state.n_colors++] = color;
		++c_token;
	    }
	    break;
	}
    }


    /* now generate options string */

    if (gif_state.flags & GIF_USE_TRANSPARENT) {
	strcat(term_options, "transparent ");
    }
    if (gif_state.flags & GIF_USE_INTERLACE) {
	strcat(term_options, "interlace ");
    }
    switch (gif_font) {
    case 0:
	strcat(term_options,"tiny ");
	break;
    case 1:
	strcat(term_options, "small ");
	break;
    case 2:
	strcat(term_options, "medium ");
	break;
    case 3:
	strcat(term_options, "large ");
	break;
    case 4:
	strcat(term_options,"giant ");
	break;
    }
    sprintf(term_options + strlen(term_options),
	    "size %d,%d ", GIF_XMAX, GIF_YMAX);

    for (i = 0; strlen(term_options) + 9 < MAX_LINE_LEN && 
	   i < gif_state.n_colors; i++) {
	sprintf(term_options + strlen(term_options),
		"x%06x ", gif_state.rgb_table[i]);
    }
}


/*
 * _init()  Called once, when the device is first selected.  This procedure
 * should set up things that only need to be set once, like handshaking and
 * character sets etc...
 */
TERM_PUBLIC void
GIF_init()
{
    gif_state.linetype = 0;
}

/*
 * _reset()  Called when gnuplot is exited, the output device changed or
 * the terminal type changed.  This procedure should reset the device, 
 * possibly flushing a buffer somewhere or generating a form feed.
 */
TERM_PUBLIC void
GIF_reset()
{
}

#ifdef PM3D

#if 0
/* use  #if 1  that's just for debugging */
void GIF_show_current_palette()
{
int i;
fprintf(stderr,"*****\n SHOW THE PALETTE! total=%i\n",gdImageColorsTotal(gif_state.image));
for (i=0; i < gdImageColorsTotal(gif_state.image); i++) {
  /* Use access macros to learn colors. */
  fprintf(stderr,"%i\tr=%d\t g=%d\tb=%d\n", i,
    gdImageRed(gif_state.image,i),
    gdImageGreen(gif_state.image,i),
    gdImageBlue(gif_state.image,i));
  }
}
#endif

/*
How this works:
Gray interval [0;1] will be mapped to interval [0;sm_palette.colors-1]
those r,g,b components are mapped by the array below
palette.offset equals 0 since gif_smooth_color[0..colors] are from ColorAllocate
*/
int gif_smooth_color[ gdMaxColors ];
  /* chooser from the colour palette */
  /* TODO: how to recover from a multiplot with two colour pm3d maps?
     They must use the same palette! Or palette size must be
     restricted to certain number of colours---a new user's option
  */

TERM_PUBLIC int GIF_make_palette (t_sm_palette *palette)
{
    int i;
    if (palette == NULL) {
	/* return maximal number of colours in a GIF palette */
	i = gdMaxColors /*256*/ - gdImageColorsTotal(gif_state.image);
	/* the latter is the number of currently allocated colours. We want
	   to allocate the rest */
	/*BACK PLEASE  fprintf(stderr,"colors in GIF palette=%i\n",(int)gdMaxColors); */
	if (i == 0) {
	    i = (sm_palette.colors <= 0) ? -1 : sm_palette.colors;
		/* (no more colours) : (previous palette (obviously multiplot mode)) */
#if 1
	    if (i > 0) fprintf(stderr,"reusing it again\n");
#endif
	}
	return i;
    }
    if (0 == gdMaxColors /*256*/ - gdImageColorsTotal(gif_state.image))
	return 0; /* reuse previous palette (without warning) */
    for (i = 0; i < sm_palette.colors; i++) {
	gif_smooth_color[i] = gdImageColorAllocate(gif_state.image,
	    (int)( palette->color[i].r * 255 + 0.5 ), /* r,g,b values for gif */
	    (int)( palette->color[i].g * 255 + 0.5 ), /* terminal are [0;255] */
	    (int)( palette->color[i].b * 255 + 0.5 ) );
	if (gif_smooth_color[i] < 0) { /* this should never happen! take away? */
	    FPRINTF((stderr, "gif_smooth_color[i]<0 cannot happen"));
	    exit(1);
	}
#if 0
	fprintf(stderr,"ALLOCATED: i=%i\t=> pal_index=%i\tr=%g g=%g b=%g\n",
	    i, gif_smooth_color[i],
	    palette->color[i].r, palette->color[i].g, palette->color[i].b );
#endif
    }
    return 0;
}


TERM_PUBLIC void GIF_set_color (double gray)
{
    int gif_color = (gray <= 0) ? 0 : (int)(gray * sm_palette.colors);
    if (gif_color >= sm_palette.colors)
	gif_color = sm_palette.colors - 1;
    /* map [0;1] to interval [0;gif_smooth_colors-1] */
    gif_state.color = gif_smooth_color[ gif_color ]; /* index to the palette */
    /*fprintf(stderr,"GIF terminal sets color gif_color=%i\n",gif_color); */
}


TERM_PUBLIC
void GIF_filled_polygon(int points, gpiPoint *corners)
{
    int i;
    /* since gpiPoint carries more than just x and y if
     * we have EXTENDED_COLOR_SPECS defined, we need to
     * copy it to the gdPointPtr struct; make it static
     * so that is faster (joze) */
    static gdPointPtr gd_corners = (gdPointPtr) 0;
    static unsigned int size = 0;
    if (points > size) {
	size = points;
	gd_corners = gp_realloc(gd_corners, sizeof(gdPoint) * size,
	    "GIF_filled_polygon->gd_corners");
    }
    for (i = 0; i < points; i++) {
	gd_corners[i].x = corners[i].x;
	gd_corners[i].y = gif_state.height - corners[i].y;
    }
    gdImageFilledPolygon(gif_state.image, gd_corners, points, gif_state.color);
    /* easy, since gdPointPtr is the same as (gdiPoint*) */
    /* if someone someday needs this routine to be NON-DESTRUCTIVE, then change
       the following line to #if 1 */
#if 0
    for (i = 0; i < points; i++)
	corners[i].y = gif_state.height - corners[i].y;
#endif
}


#endif

/*
 * _graphics()  Called just before a plot is going to be displayed.  This
 * procedure should set the device into graphics mode.  Devices which can't
 * be used as terminals (like plotters) will probably be in graphics mode 
 * always and therefore won't need this.
 */
TERM_PUBLIC void
GIF_graphics()
{
    int i;
    unsigned int rgb;

    gif_state.font = GIF_font;
    gif_state.color = 0;
    gif_state.image = gdImageCreate((int) (xsize * GIF_XMAX),
				    (int) (ysize * GIF_YMAX));
    gif_state.height = (int) (ysize * GIF_YMAX - 1);
    gif_state.charw = term->h_char;	/* gif_state.font->w; */
    gif_state.charh = term->v_char;	/* gif_state.font->h; */
    for (i = gif_state.n_colors; i < WEB_N_COLORS; i++)
	gif_state.rgb_table[i] = 
	    (web_color_rgbs[i].r << 16) |
	    (web_color_rgbs[i].g << 8) |
	    web_color_rgbs[i].b;
    if (gif_state.n_colors < WEB_N_COLORS)
	gif_state.n_colors = WEB_N_COLORS;
    for (i = 0; i < gif_state.n_colors; i++) {
	rgb = gif_state.rgb_table[i];
	gif_state.color_table[i] =
	    gdImageColorAllocate(gif_state.image, (rgb >> 16) & 0xff,
				 (rgb >> 8) & 0xff, rgb & 0xff);
    }
    if (gif_state.flags & GIF_USE_TRANSPARENT)
	gdImageColorTransparent(gif_state.image,
				gif_state.color_table[0]);
    else
	gdImageColorTransparent(gif_state.image, -1);
}

/* 
 * _text()  Called immediately after a plot is displayed.  This procedure 
 * should set the device back into text mode if it is also a terminal, so
 * that commands can be seen as they're typed.  Again, this will probably
 * do nothing if the device can't be used as a terminal.
 */
TERM_PUBLIC void
GIF_text()
{
    if (gif_state.flags & GIF_USE_INTERLACE)
	gdImageInterlace(gif_state.image, 1);
    gdImageGif(gif_state.image, gpoutfile);
    gdImageDestroy(gif_state.image);
}

/* _move(x,y)  Called at the start of a line.  The cursor should move to the
 * (x,y) position without drawing.
 */
TERM_PUBLIC void
GIF_move(unsigned int x, unsigned int y)
{
    gif_state.x = x;
    gif_state.y = y;
}

/* _vector(x,y)  Called when a line is to be drawn.  This should display a line
 * from the last (x,y) position given by _move() or _vector() to this new (x,y)
 * position.
 */
TERM_PUBLIC void
GIF_vector(unsigned int x, unsigned int y)
{
    int gif_linetype_dotted[5];

    if (gif_state.linetype == -1) {
	gif_linetype_dotted[0] = gif_state.color_table[2];
	gif_linetype_dotted[1] = gif_state.color_table[2];
	gif_linetype_dotted[2] = gif_state.color_table[0];
	gif_linetype_dotted[3] = gif_state.color_table[0];
	gif_linetype_dotted[4] = gif_state.color_table[0];

	gdImageSetStyle(gif_state.image, gif_linetype_dotted, 5);
	gdImageLine(gif_state.image, gif_state.x, gif_state.height - gif_state.y,
		    x, gif_state.height - y, gdStyled);
    } else {
	gdImageLine(gif_state.image, gif_state.x, gif_state.height - gif_state.y,
		    x, gif_state.height - y, gif_state.color);
    }
    gif_state.x = x;
    gif_state.y = y;
}

/* _linetype(lt)  Called to set the line type before text is displayed or
 * line(s) plotted.  This procedure should select a pen color or line
 * style if the device has these capabilities.  
 * lt is an integer from -2 to 0 or greater.  
 * An lt of -2 is used for the border of the plot.
 * An lt of -1 is used for the X and Y axes.  
 * lt 0 and upwards are used for plots 0 and upwards.
 * If _linetype() is called with lt greater than the available line types, 
 * it should map it to one of the available line types.
 * Most drivers provide 9 different linetypes (lt is 0 to 8).
 */
TERM_PUBLIC void
GIF_linetype(int type)
{
    if (type >= (gif_state.n_colors - 3))
	type %= (gif_state.n_colors - 3);

    gif_state.color = gif_state.color_table[type + 3];
    gif_state.linetype = type;
}

/* _put_text(x,y,str)  Called to display text at the (x,y) position, 
 * while in graphics mode.   The text should be vertically (with respect 
 * to the text) justified about (x,y).  The text is rotated according 
 * to _text_angle and then horizontally (with respect to the text)
 * justified according to _justify_text.
 */
TERM_PUBLIC void
GIF_put_text(unsigned int x, unsigned int y, const char *string)
{
    if (gif_state.angle == 1) {
	x -= gif_state.charh / 2;
	gdImageStringUp(gif_state.image, gif_state.font,
			x, gif_state.height - y,
			(unsigned char *)string, gif_state.color);
    } else {
	y += gif_state.charh / 2;
	gdImageString(gif_state.image, gif_state.font,
		      x, gif_state.height - y,
		      (unsigned char *)string, gif_state.color);
    }
}

/* _text_angle(ang)  Called to rotate the text angle when placing the y label.
 * If ang = 0 then text is horizontal.  If ang = 1 then text is vertically
 * upwards.  Returns TRUE if text can be rotated, FALSE otherwise.
 */
TERM_PUBLIC int
GIF_text_angle(int ang)
{
    gif_state.angle = (ang ? 1 : 0);
    return TRUE;
}

TERM_PUBLIC int
GIF_set_font(const char *fontname)
{
    char name[32];
    int  sep;
    gdFontPtr font;

    sep = strcspn(fontname,",");
    strncpy(name,fontname,sep);
    name[sep] = NUL;

    if (!strcmp(fontname,"small"))
	font = gdFontSmall;
    else if (!strcmp(fontname,"medium"))
	font = gdFontMediumBold;
    else if(!strcmp(fontname,"large"))
	font = gdFontLarge;
    else if(!strcmp(fontname,"giant"))
	font = gdFontGiant;
    else if(!strcmp(fontname,"tiny"))
	font = gdFontTiny;
    else
	font = GIF_font;

    gif_state.charw = font->w;
    gif_state.charh = font->h;

    gif_state.font = font;

    return TRUE;
}

TERM_PUBLIC void
GIF_boxfill(style, x, y, w, h)
    int style;
    unsigned int x, y, w, h;
{
    /* Only solid filling style is supported, i.e. no pattern nor density. */
    gdImageFilledRectangle(gif_state.image, x, gif_state.height-(y+h), 
	    x+w, gif_state.height-y, gif_state.color);
}
    
#endif /* TERM_BODY */
#ifdef TERM_TABLE

TERM_TABLE_START(gif_driver)
    "gif", 
#ifdef PNG_FOR_GIF
    "GIF format [mode] [fontsize] [size] [colors] (will actually generate PNG images)",
#else
    "GIF format [mode] [fontsize] [size] [colors]",
#endif
    GREG_XMAX, GREG_YMAX, GIF_VCHAR, GIF_HCHAR,
    GIF_VTIC, GIF_HTIC, GIF_options, GIF_init, GIF_reset,
    GIF_text, null_scale, GIF_graphics, GIF_move, GIF_vector,
    GIF_linetype, GIF_put_text, GIF_text_angle,
    null_justify_text, do_point, do_arrow, GIF_set_font,
    0,				/* pointsize */
    TERM_CAN_MULTIPLOT | TERM_BINARY
    , 0 /*suspend*/, 0 /*resume*/, 
    GIF_boxfill,   0 /*linewidth*/
#ifdef PM3D
#ifdef USE_MOUSE
    , 0, 0, 0, 0, 0 /* no mouse support for gif terminal */
#endif
    , GIF_make_palette,
    0, /* previous_palette() ... no, single array of 256 colours for GIF */
    GIF_set_color,
    GIF_filled_polygon
#endif
TERM_TABLE_END(gif_driver)

#undef LAST_TERM
#define LAST_TERM gif_driver

#endif /* TERM_TABLE */
#endif /* TERM_PROTO_ONLY */

#ifdef TERM_HELP
START_HELP(gif)
"1 gif",
"?commands set terminal gif",
"?set terminal gif",
"?set term gif",
"?terminal gif",
"?term gif",
"?gif",
" The `gif` terminal driver generates output in GIF format.  It uses Thomas",
" Boutell's gd library, which is available from http://www.boutell.com/gd/",
" Support for GIF output was removed from the gd library beginning with ",
" version 1.6; newer versions support PNG output instead.",
#ifdef PNG_FOR_GIF
"",
" >>> This copy of gnuplot was configured to produce PNG images <<<",
" >>> instead of GIF images when 'set term gif' is selected.    <<<",
#endif
"",
" Syntax:",
"       set terminal gif {transparent} {interlace}",
"                        {tiny | small | medium | large | giant}",
"                        {size <x>,<y>}",
"                        {<color0> <color1> <color2> ...}",
"",
" `transparent` instructs the driver to generate transparent GIFs.  The first",
" color will be the transparent one.",
"",
" `interlace` instructs the driver to generate interlaced GIFs.",
"",
" The choice of fonts is `tiny` (5x8 pixels), `small` (6x12 pixels), `medium`",
" (7x13 Bold), `large` (8x16) or `giant` (9x15 pixels)",
"",
" The size <x,y> is given in pixels---it defaults to 640x480.  The number of",
" pixels can be also modified by scaling with the `set size` command.",
"",
" Each color must be of the form 'xrrggbb', where x is the literal character",
" 'x' and 'rrggbb' are the red, green and blue components in hex.  For example,",
" 'x00ff00' is green.  The background color is set first, then the border",
" colors, then the X & Y axis colors, then the plotting colors.  The maximum",
" number of colors that can be set is 256.",
"",
" Examples:",
"       set terminal gif small size 640,480 \\",
"                        xffffff x000000 x404040 \\",
"                        xff0000 xffa500 x66cdaa xcdb5cd \\",
"                        xadd8e6 x0000ff xdda0dd x9500d3    # defaults",
"",
" which uses white for the non-transparent background, black for borders, gray",
" for the axes, and red, orange, medium aquamarine, thistle 3, light blue, blue,",
" plum and dark violet for eight plotting colors.",
"",
"       set terminal gif transparent xffffff \\",
"                        x000000 x202020 x404040 x606060 \\",
"                        x808080 xA0A0A0 xC0C0C0 xE0E0E0 \\",
" which uses white for the transparent background, black for borders, dark",
" gray for axes, and a gray-scale for the six plotting colors.",
"",
" The page size is 640x480 pixels.  The `gif` driver can create either color",
" or monochromatic output, but you have no control over which is produced.",
"",
" The current version of the `gif` driver does not support animated GIFs."
END_HELP(gif)
#endif /* TERM_HELP */

/*
 * Local Variables:
 * mode:C
 * End:
 */