=================================================================== RCS file: /home/cvs/OpenXM_contrib/gnuplot/term/Attic/png.trm,v retrieving revision 1.1 retrieving revision 1.1.1.3 diff -u -p -r1.1 -r1.1.1.3 --- OpenXM_contrib/gnuplot/term/Attic/png.trm 2000/01/09 17:01:15 1.1 +++ OpenXM_contrib/gnuplot/term/Attic/png.trm 2003/09/15 07:09:38 1.1.1.3 @@ -1,5 +1,5 @@ /* - * $Id: png.trm,v 1.1 2000/01/09 17:01:15 maekawa Exp $ + * $Id: png.trm,v 1.1.1.3 2003/09/15 07:09:38 ohara Exp $ * */ @@ -45,6 +45,9 @@ * Alexander Lehmann * derived from pbm.trm by Russell Lang * + * Eric S. Raymond update for pnglib-1.0.3; transparency. + * H.-B. Broeker fixes to Eric's changes + * * send your comments or suggestions to (info-gnuplot@dartmouth.edu). * */ @@ -69,16 +72,24 @@ register_term(png_driver) #endif #ifdef TERM_PROTO -TERM_PUBLIC void PNGoptions __PROTO((void)); -TERM_PUBLIC void PNGinit __PROTO((void)); -TERM_PUBLIC void PNGreset __PROTO((void)); -TERM_PUBLIC void PNGsetfont __PROTO((void)); -TERM_PUBLIC void PNGgraphics __PROTO((void)); -TERM_PUBLIC void PNGtext __PROTO((void)); -TERM_PUBLIC void PNGlinetype __PROTO((int linetype)); -TERM_PUBLIC void PNGpoint __PROTO((unsigned int x, unsigned int y, int point)); +TERM_PUBLIC void PNG_options __PROTO((void)); +TERM_PUBLIC void PNG_init __PROTO((void)); +TERM_PUBLIC void PNG_reset __PROTO((void)); +TERM_PUBLIC void PNG_setfont __PROTO((void)); +TERM_PUBLIC void PNG_graphics __PROTO((void)); +TERM_PUBLIC void PNG_text __PROTO((void)); +TERM_PUBLIC void PNG_linetype __PROTO((int linetype)); +TERM_PUBLIC void PNG_point __PROTO((unsigned int x, unsigned int y, int point)); #endif /* TERM_PROTO */ +/* make XMAX and YMAX a multiple of 8 */ +#define PNG_XMAX (640) +#define PNG_YMAX (480) +#define PNG_VCHAR (FNT5X9_VCHAR) +#define PNG_HCHAR (FNT5X9_VCHAR) +#define PNG_VTIC FNT5X9_HBITS +#define PNG_HTIC FNT5X9_HBITS + #ifdef TERM_BODY #include "png.h" @@ -90,92 +101,135 @@ TERM_PUBLIC void PNGpoint __PROTO((unsigned int x, uns /* png version test now in configure */ -/* From version.c */ -extern char version[]; -extern char patchlevel[]; - -/* make XMAX and YMAX a multiple of 8 */ -#define PNG_XMAX (640) -#define PNG_YMAX (480) -#define PNG_VCHAR (FNT5X9_VCHAR) -#define PNG_HCHAR (FNT5X9_VCHAR) -#define PNG_VTIC FNT5X9_HBITS -#define PNG_HTIC FNT5X9_HBITS - static int png_font = 1; /* small font */ static int png_mode = 0; /* 0:monochrome 1:gray 2:color */ +static int png_transparent = 0; /* generate transparent first color */ /* 7=black, 0=white */ static int png_gray[] = { 7, 1, 6, 5, 4, 3, 2, 1, 7 }; /* grays */ -/* bit3=!intensify, bit2=!red, bit1=!green, bit0=!blue */ -static int png_color_table[] ={ 15, 8, 3, 5, 6, 4, 2, 1, 11, 13, 14 }; /* colors */ -static png_color png_palette[16]; +static png_color png_palette[WEB_N_COLORS]; -void PNGoptions() +TERM_PUBLIC void +PNG_options() { - png_font = 1; - png_mode = 0; + unsigned short rgb_color[3]; + int n_colors = 0; + char *string; + int i; + rgb_color[0] = 0; + rgb_color[1] = 0; + rgb_color[2] = 0; + + png_font = 1; /* small */ + png_mode = 2; /* color */ + png_transparent = 0; /* use opaque image background */ + term_options[0] = NUL; while (!END_OF_COMMAND) { - if (almost_equals(c_token, "s$mall")) - png_font = 1; - else if (almost_equals(c_token, "me$dium")) - png_font = 2; - else if (almost_equals(c_token, "l$arge")) - png_font = 3; - else if (almost_equals(c_token, "mo$nochrome")) - png_mode = 0; - else if (almost_equals(c_token, "g$ray")) - png_mode = 1; - else if (almost_equals(c_token, "c$olor") - || almost_equals(c_token, "c$olour")) - png_mode = 2; - else { - /* reset to default, since term is already set */ - png_font = 1; - png_mode = 0; - int_error("expecting: {small, medium, large} and {monochrome, gray, color}", c_token); - } - c_token++; + if (almost_equals(c_token, "s$mall")) + png_font = 1; + else if (almost_equals(c_token, "me$dium")) + png_font = 2; + else if (almost_equals(c_token, "l$arge")) + png_font = 3; + else if (almost_equals(c_token, "mo$nochrome")) + png_mode = 0; + else if (almost_equals(c_token, "g$ray")) + png_mode = 1; + else if (almost_equals(c_token, "c$olor") + || almost_equals(c_token, "c$olour")) + png_mode = 2; + else if (almost_equals(c_token, "t$ransparent")) + png_transparent = 1; + else if (almost_equals(c_token, "not$ransparent")) + png_transparent = 0; + else { + /* set color */ + string = input_line + token[c_token].start_index; + + if (string[0] == 'x') { + /* HBB 991123: read in as *shorts*, not ints! */ + if (sscanf(string, "x%2hx%2hx%2hx", &rgb_color[0], &rgb_color[1], &rgb_color[2] ) != 3) { + int_error("invalid color spec, must be xRRGGBB", c_token); + } + } else + int_error("expecting: {small, medium, large},[no]transparent, or {monochrome, gray, color, [xRRGGBB] }", c_token); + + if (n_colors >= WEB_N_COLORS) { + int_warn("too many colors, ignoring", c_token); + /* Magic number abuse guards against + * "> WEB_N_COLORS warning" scroll fests. */ + if (!END_OF_COMMAND) { + while (!END_OF_COMMAND) + ++c_token; --c_token; + } + } else { + web_color_rgbs[n_colors].r = rgb_color[0]; + web_color_rgbs[n_colors].g = rgb_color[1]; + web_color_rgbs[n_colors].b = rgb_color[2]; + n_colors++; + } + } + c_token++; } /* setup options string */ + /* HBB 991008: moved this block to here, so 'transparent' gets + * printed out first. Don't print 'notransparent', for now, to + * protect older gnuplots. Scripts with 'transparent' in them + * won't work as wanted, with older versions, so put it here. */ + if (png_transparent) + strcat(term_options, " transparent"); + switch (png_font) { - case 1: - strcat(term_options, "small"); + case 3: + strcat(term_options, " large"); break; case 2: - strcat(term_options, "medium"); + strcat(term_options, " medium"); break; - case 3: - strcat(term_options, "large"); + case 1: + default: + strcat(term_options, " small"); break; } switch (png_mode) { - case 0: - strcat(term_options, " monochrome"); + case 2: + strcat(term_options, " color"); break; case 1: strcat(term_options, " gray"); break; - case 2: - strcat(term_options, " color"); + case 0: + default: + strcat(term_options, " monochrome"); break; } + + for (i = 0; strlen(term_options) + 9 < MAX_LINE_LEN && + i < n_colors ; i++ ) { + sprintf(term_options,"%s x%02x%02x%02x", + term_options, + web_color_rgbs[i].r, + web_color_rgbs[i].g, + web_color_rgbs[i].b); + } } -void PNGinit() +TERM_PUBLIC void +PNG_init() { - PNGsetfont(); /* HBB 980226: do this here! */ + PNG_setfont(); /* HBB 980226: do this here! */ } -void PNGreset() +TERM_PUBLIC void +PNG_reset() { #ifdef VMS fflush_binary(); @@ -183,15 +237,16 @@ void PNGreset() } -void PNGsetfont() +TERM_PUBLIC void +PNG_setfont() { switch (png_font) { - case 1: - b_charsize(FNT5X9); - term->v_char = FNT5X9_VCHAR; - term->h_char = FNT5X9_HCHAR; - term->v_tic = FNT5X9_HBITS; - term->h_tic = FNT5X9_HBITS; + case 3: + b_charsize(FNT13X25); + term->v_char = FNT13X25_VCHAR; + term->h_char = FNT13X25_HCHAR; + term->v_tic = FNT13X25_HBITS; + term->h_tic = FNT13X25_HBITS; break; case 2: b_charsize(FNT9X17); @@ -200,30 +255,33 @@ void PNGsetfont() term->v_tic = FNT9X17_HBITS; term->h_tic = FNT9X17_HBITS; break; - case 3: - b_charsize(FNT13X25); - term->v_char = FNT13X25_VCHAR; - term->h_char = FNT13X25_HCHAR; - term->v_tic = FNT13X25_HBITS; - term->h_tic = FNT13X25_HBITS; + case 1: + default: + b_charsize(FNT5X9); + term->v_char = FNT5X9_VCHAR; + term->h_char = FNT5X9_HCHAR; + term->v_tic = FNT5X9_HBITS; + term->h_tic = FNT5X9_HBITS; break; } } -void PNGgraphics() +TERM_PUBLIC void +PNG_graphics() { - int numplanes; + int numplanes = 1; switch (png_mode) { - case 0: - numplanes = 1; + case 2: + numplanes = 8; break; case 1: numplanes = 3; break; - case 2: - numplanes = 4; + case 0: + default: + numplanes = 1; break; } @@ -239,17 +297,18 @@ void PNGgraphics() b_setlinetype(0); /* solid lines */ } -void PNGtext() +TERM_PUBLIC void +PNG_text() { - register int x, j, row; png_structp png_ptr; png_infop info_ptr; - register int i, value; png_bytep prow; - int mask, plane1, plane2, plane3, plane4; - int red, green, blue; png_text pngtext, *pngtext_copy; + png_byte pal_trans[1]; char text[100]; + register int x, i, j; +/* register int row, value; */ +/* int mask, plane1, plane2, plane3, plane4; */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { @@ -268,65 +327,83 @@ void PNGtext() b_freebitmap(); return; } + memset(prow,0,sizeof(prow)); if (setjmp(png_ptr->jmpbuf)) { png_destroy_write_struct(&png_ptr, &info_ptr); free(prow); b_freebitmap(); return; } + +#ifdef __OLD_PNGLIB__ + /* deprecated and no longer necessary */ png_info_init(info_ptr); - png_write_init(png_ptr); + png_write_init(png_ptr); */ +#endif /* __OLD_PNGLIB__ */ png_init_io(png_ptr, gpoutfile); info_ptr->width = b_ysize; info_ptr->height = b_xsize; - info_ptr->bit_depth = png_mode == 0 ? 1 : 4; + info_ptr->bit_depth = png_mode == 0 ? 1 : 8; info_ptr->color_type = png_mode == 2 ? PNG_COLOR_TYPE_PALETTE : PNG_COLOR_TYPE_GRAY; if (png_mode == 2) { info_ptr->valid |= PNG_INFO_PLTE; info_ptr->palette = png_palette; - info_ptr->num_palette = 16; + info_ptr->num_palette = sizeof(png_palette)/sizeof(png_palette[0]); } if (png_mode != 0) { info_ptr->valid |= PNG_INFO_sBIT; if (png_mode == 1) { info_ptr->sig_bit.gray = 3; png_set_shift(png_ptr, &(info_ptr->sig_bit)); - } else { - info_ptr->sig_bit.red = 2; - info_ptr->sig_bit.green = 2; - info_ptr->sig_bit.blue = 2; + } + else { + /* HBB 991123: we're now using the full 8 bits per color + * component... */ + info_ptr->sig_bit.red = 8; + info_ptr->sig_bit.green = 8; + info_ptr->sig_bit.blue = 8; } } + info_ptr->interlace_type = 0; + if (png_mode == 0) png_set_invert_mono(png_ptr); - if (png_mode == 2) - for (i = 0; i < 16; i++) { - red = (i & 4) ? 1 : 3; - green = (i & 2) ? 1 : 3; - blue = (i & 1) ? 1 : 3; - if (i & 8) { - red--; - green--; - blue--; - } - png_palette[i].red = red * 85; - png_palette[i].green = green * 85; - png_palette[i].blue = blue * 85; + if (png_mode == 2) { + if (png_transparent) { + info_ptr->valid |= PNG_INFO_tRNS; + info_ptr->num_trans = 1; + pal_trans[0] = 0; + info_ptr->trans=pal_trans; } - sprintf(text, "gnuplot %sversion %s patchlevel %s", OS, version, patchlevel); + for (i = 0; i < WEB_N_COLORS; i++) { + png_palette[i].red = web_color_rgbs[i].r; + png_palette[i].green = web_color_rgbs[i].g; + png_palette[i].blue = web_color_rgbs[i].b; + } + } + sprintf(text, "gnuplot version %s patchlevel %s on %s %s", + gnuplot_version, gnuplot_patchlevel, os_name, os_rel); + pngtext.compression = -1; pngtext.key = "Software"; pngtext.text = text; pngtext.text_length = strlen(text); pngtext_copy = malloc(sizeof(*pngtext_copy)); + if (!pngtext_copy) { + png_destroy_write_struct(&png_ptr, &info_ptr); + free(prow); + b_freebitmap(); + return; + } + memset(pngtext_copy,0,sizeof(pngtext_copy)); *pngtext_copy = pngtext; info_ptr->num_text = 1; info_ptr->text = pngtext_copy; @@ -341,6 +418,7 @@ void PNGtext() /* dump bitmap in raster mode */ for (x = b_xsize - 1; x >= 0; x--) { +#if 0 row = (b_ysize / 8) - 1; for (j = row; j >= 0; j--) { mask = 0x80; @@ -370,10 +448,14 @@ void PNGtext() if (png_mode == 1) value = 7 - value; - prow[(row - j) * 8 + i] = (png_byte) value; + prow[(row - j) * 8 + i] = (png_byte) (value & 0xFF) ; mask >>= 1; } } +#else + for (j=b_ysize - 1; j>= 0; j--) + prow[j] = (png_byte)b_getpixel(j, x); +#endif png_write_rows(png_ptr, &prow, 1); } @@ -383,27 +465,57 @@ void PNGtext() b_freebitmap(); } -void PNGlinetype(linetype) +/* _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 +PNG_linetype(linetype) int linetype; { switch (png_mode) { - case 0: - b_setlinetype(linetype); + /* HBB 991008: this once made the grid lines and axes (-1) look the + * same as the borders (-2). That's ugly, IMHO. GIF uses a + * dashed line, for this, but libpng doesn't seem able to do + * that. But a look into the palette turns up that color 2 + * is grey, and is currently unused... Let's see: */ + case 2: + + if (linetype == -2) + linetype = 1; + else if (linetype == -1) + linetype = 2; + + else { + /* HBB 991008: moved the += 3 down, so colors 0, 1, 2 are + * _not_ used by the regular plots, as it should be */ + if (linetype >= (WEB_N_COLORS - 3)) + linetype %= (WEB_N_COLORS - 3); + linetype += 3; + } + b_setvalue(linetype); break; case 1: if (linetype >= 7) linetype %= 7; b_setvalue(png_gray[linetype + 2]); break; - case 2: - if (linetype >= 9) - linetype %= 9; - b_setvalue(png_color_table[linetype + 2]); + case 0: + default: + b_setlinetype(linetype); break; } } -void PNGpoint(x, y, point) +TERM_PUBLIC void +PNG_point(x, y, point) unsigned int x, y; int point; { @@ -421,10 +533,10 @@ TERM_TABLE_START(png_driver) "png", "Portable Network Graphics [small medium large] [monochrome gray color]", PNG_XMAX, PNG_YMAX, PNG_VCHAR, - PNG_HCHAR, PNG_VTIC, PNG_HTIC, PNGoptions, - PNGinit, PNGreset, PNGtext, null_scale, - PNGgraphics, b_move, b_vector, PNGlinetype, - b_put_text, b_text_angle, null_justify_text, PNGpoint, + PNG_HCHAR, PNG_VTIC, PNG_HTIC, PNG_options, + PNG_init, PNG_reset, PNG_text, null_scale, + PNG_graphics, b_move, b_vector, PNG_linetype, + b_put_text, b_text_angle, null_justify_text, PNG_point, do_arrow, set_font_null, 0, /* pointsize */ TERM_CAN_MULTIPLOT | TERM_BINARY @@ -446,12 +558,26 @@ START_HELP(png) "?png", " The `png` terminal driver supports Portable Network Graphics. To compile it,", " you will need the third-party libraries \"libpng\" and \"zlib\"; both are", -" available at ftp://ftp.uu.net/graphics/png. `png` has two options.", +" available at http://www.cdrom.com/pub/png/. `png` has four options.", "", +" By default, the `png` terminal driver uses a shared Web-friendy palette.", +"", " Syntax:", " set terminal png {small | medium | large}", +" {transparent | notransparent}", " {monochrome | gray | color}", +" { ...}", "", -" The defaults are small (fontsize) and monochrome." +" `transparent` instructs the driver to generate transparent PNGs. The first", +" color will be the transparent one.", +"", +" The defaults are small (fontsize) and color. Default size of the output", +" is 640*480 pixel. ", +"", +" 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 currently 99." END_HELP(png) #endif /* TERM_HELP */