[BACK]Return to gif.trm CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot / term

File: [local] / OpenXM_contrib / gnuplot / term / Attic / gif.trm (download)

Revision 1.1.1.3 (vendor branch), Mon Sep 15 07:09:36 2003 UTC (20 years, 8 months ago) by ohara
Branch: GNUPLOT
CVS Tags: VERSION_3_7_3, RELEASE_1_2_3, RELEASE_1_2_2_KNOPPIX_b, RELEASE_1_2_2_KNOPPIX
Changes since 1.1.1.2: +11 -5 lines

Import gnuplot 3.7.3

/*
 * $Id: gif.trm,v 1.12.2.7 2002/12/12 12:56:44 lhecking 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.
 *
 */

#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, char str[]));
TERM_PUBLIC int GIF_text_angle __PROTO((int ang));
TERM_PUBLIC void GIF_reset __PROTO((void));

#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

/*
 * _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) {
	if (almost_equals(c_token, "t$ransparent")) {
	    gif_state.flags |= GIF_USE_TRANSPARENT;
	    ++c_token;
	} else if (almost_equals(c_token, "i$nterlace")) {
	    gif_state.flags |= GIF_USE_INTERLACE;
	    ++c_token;
	} else if (almost_equals(c_token, "ti$ny")) {
	    GIF_font=gdFontTiny;
	    gif_font = 0;
	    term->v_char = (unsigned int)(8);
	    term->h_char = (unsigned int)(5);
	    ++c_token;
	} else if (almost_equals(c_token, "s$mall")) {
	    GIF_font = gdFontSmall;
	    gif_font = 1;
	    term->v_char = (unsigned int) (12);
	    term->h_char = (unsigned int) (6);
	    ++c_token;
	} else if (almost_equals(c_token, "m$edium")) {
	    GIF_font = gdFontMediumBold;
	    gif_font = 2;
	    term->v_char = (unsigned int) (13);
	    term->h_char = (unsigned int) (7);
	    ++c_token;
	} else if (almost_equals(c_token, "l$arge")) {
	    GIF_font = gdFontLarge;
	    gif_font = 3;
	    term->v_char = (unsigned int) (16);
	    term->h_char = (unsigned int) (8);
	    ++c_token;
	} else if (almost_equals(c_token, "g$iant")) {
	    GIF_font=gdFontGiant;
	    gif_font = 4;
	    term->v_char = (unsigned int)(15);
	    term->h_char = (unsigned int)(9);
	    ++c_token;
	} else if (almost_equals(c_token, "si$ze")) {
	    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;
		}
	    }
	} else {                /* not "size" */
	    string = input_line + token[c_token].start_index;
	    if (sscanf(string, "x%lx", &color) != 1) {
		int_error("invalid color spec, must be xRRGGBB",c_token);
	    } else if (gif_state.n_colors == GIF_MAX_COLORS) {
		int_warn("too many colors, ignoring", c_token);
		++c_token;
	    } else {
		gif_state.rgb_table[gif_state.n_colors++] = color;
		++c_token;
	    }
	}
    }


    /* 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()
{
}

/*
 * _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, char *string)
{
    if (gif_state.angle == 1) {
	x -= gif_state.charh / 2;
	gdImageStringUp(gif_state.image, gif_state.font,
			x, gif_state.height - y,
			string, gif_state.color);
    } else {
	y += gif_state.charh / 2;
	gdImageString(gif_state.image, gif_state.font,
		      x, gif_state.height - y,
		      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;
    return TRUE;
}

TERM_PUBLIC int
GIF_set_font(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;
}

#endif /* TERM_BODY */
#ifdef TERM_TABLE

TERM_TABLE_START(gif_driver)
    "gif", "GIF format [mode] [fontsize] [size] [colors]",
    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
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/",
"",
" By default, the `gif` terminal driver uses a shared Web-friendy palette."
"",
" 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:
 */