--- /dev/null
+/* Hello, Emacs, this is -*-C-*-
+ * $Id: pbm.trm,v 1.26.2.1 2006/11/23 05:36:01 sfeam Exp $
+ *
+ */
+
+/* GNUPLOT - pbm.trm */
+
+/*[
+ * Copyright 1990 - 1993, 1998, 2004
+ *
+ * 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:
+ * pbm
+ *
+ * AUTHORS
+ * Russell Lang
+ *
+ * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
+ *
+ */
+
+/* The following pbmplus drivers use the generic bit mapped graphics
+ routines from bitmap.c to build up a bit map in memory. The driver
+ interchanges colomns and lines in order to access entire lines
+ easily and returns the lines to get bits in the right order :
+ (x,y) -> (y,XMAX-1-x). */
+/* This interchange is done by calling b_makebitmap() with reversed
+ xmax and ymax, and then setting b_rastermode to TRUE. b_setpixel()
+ will then perform the interchange before each pixel is plotted */
+/* See Jef Poskanzer's excellent PBMplus package for more details of
+ the Portable BitMap format and for programs to convert PBM files
+ to other bitmap formats. */
+
+#include "driver.h"
+
+#ifdef TERM_REGISTER
+register_term(pbm_driver)
+#endif
+
+#ifdef TERM_PROTO
+TERM_PUBLIC void PBM_options __PROTO((void));
+TERM_PUBLIC void PBM_init __PROTO((void));
+TERM_PUBLIC void PBM_reset __PROTO((void));
+TERM_PUBLIC void PBM_setfont __PROTO((void));
+TERM_PUBLIC void PBM_graphics __PROTO((void));
+TERM_PUBLIC void PBM_monotext __PROTO((void));
+TERM_PUBLIC void PBM_graytext __PROTO((void));
+TERM_PUBLIC void PBM_colortext __PROTO((void));
+TERM_PUBLIC void PBM_text __PROTO((void));
+TERM_PUBLIC void PBM_linetype __PROTO((int linetype));
+TERM_PUBLIC void PBM_point __PROTO((unsigned int x, unsigned int y, int point));
+#endif /* TERM_PROTO */
+
+/* make XMAX and YMAX a multiple of 8 */
+#define PBM_XMAX (640)
+#define PBM_YMAX (480)
+#define PBM_VCHAR (FNT5X9_VCHAR)
+#define PBM_HCHAR (FNT5X9_VCHAR)
+#define PBM_VTIC FNT5X9_HBITS
+#define PBM_HTIC FNT5X9_HBITS
+
+#ifdef TERM_BODY
+
+static int pbm_font = 1; /* small font */
+static int pbm_mode = 0; /* 0:monochrome 1:gray 2:color */
+
+/* Only needed for dubious backwards compatibility with 'set size'
+ * in pre-4.2 versions that didn't support 'set term size'
+ */
+static TBOOLEAN PBM_explicit_size = FALSE;
+
+/* 7=black, 0=white */
+static int pgm_gray[] = { 7, 1, 6, 5, 4, 3, 2, 1, 7 }; /* grays */
+/* bit3=!intensify, bit2=!red, bit1=!green, bit0=!blue */
+static int ppm_color[] ={ 15, 8, 3, 5, 6, 2, 4, 1, 11, 13, 14 }; /* colors */
+
+enum PBM_id {
+ PBM_SMALL, PBM_MEDIUM, PBM_LARGE,
+ PBM_MONOCHROME, PBM_GRAY, PBM_COLOR, PBM_SIZE,
+ PBM_OTHER
+};
+
+static struct gen_table PBM_opts[] =
+{
+ { "s$mall", PBM_SMALL },
+ { "me$dium", PBM_MEDIUM },
+ { "l$arge", PBM_LARGE },
+ { "mo$nochrome", PBM_MONOCHROME },
+ { "g$ray", PBM_GRAY },
+ { "c$olor", PBM_COLOR },
+ { "c$olour", PBM_COLOR },
+ { "size", PBM_SIZE },
+ { NULL, PBM_OTHER }
+};
+
+TERM_PUBLIC void
+PBM_options()
+{
+ int xpixels = PBM_XMAX;
+ int ypixels = PBM_YMAX;
+ struct value a;
+ pbm_font = 1;
+ pbm_mode = 0;
+
+ term_options[0] = NUL;
+
+ while (!END_OF_COMMAND) {
+ switch(lookup_table(&PBM_opts[0],c_token)) {
+ case PBM_SMALL:
+ pbm_font = 1;
+ c_token++;
+ break;
+ case PBM_MEDIUM:
+ pbm_font = 2;
+ c_token++;
+ break;
+ case PBM_LARGE:
+ pbm_font = 3;
+ c_token++;
+ break;
+ case PBM_MONOCHROME:
+ pbm_mode = 0;
+ c_token++;
+ break;
+ case PBM_GRAY:
+ pbm_mode = 1;
+ c_token++;
+ break;
+ case PBM_COLOR:
+ pbm_mode = 2;
+ c_token++;
+ break;
+ case PBM_SIZE:
+ c_token++;
+ if (END_OF_COMMAND) {
+ term->xmax = PBM_XMAX;
+ term->ymax = PBM_YMAX;
+ PBM_explicit_size = FALSE;
+ } else {
+ xpixels = real(const_express(&a));
+ if (equals(c_token, ",")) {
+ c_token++;
+ ypixels = real(const_express(&a));
+ }
+ PBM_explicit_size = TRUE;
+ }
+ if (xpixels > 0)
+ term->xmax = xpixels;
+ if (ypixels > 0)
+ term->ymax = ypixels;
+ break;
+ case PBM_OTHER:
+ default:
+ /* reset to default, since term is already set */
+ pbm_font = 1;
+ pbm_mode = 0;
+ int_error(c_token, "expecting: {small, medium, large} and {monochrome, gray, color}");
+ break;
+ }
+ }
+
+ /* setup options string */
+
+ switch (pbm_font) {
+ case 1:
+ strcat(term_options, "small");
+ break;
+ case 2:
+ strcat(term_options, "medium");
+ break;
+ case 3:
+ strcat(term_options, "large");
+ break;
+ }
+
+ switch (pbm_mode) {
+ case 0:
+ strcat(term_options, " monochrome");
+ break;
+ case 1:
+ strcat(term_options, " gray");
+ break;
+ case 2:
+ strcat(term_options, " color");
+ break;
+ }
+
+ if (PBM_explicit_size)
+ sprintf(term_options + strlen(term_options), " size %d,%d",
+ term->xmax, term->ymax);
+}
+
+
+TERM_PUBLIC void
+PBM_init()
+{
+ PBM_setfont(); /* HBB 980226: call it here! */
+}
+
+
+TERM_PUBLIC void
+PBM_reset()
+{
+#ifdef VMS
+ fflush_binary();
+#endif /* VMS */
+}
+
+
+TERM_PUBLIC void
+PBM_setfont()
+{
+ switch (pbm_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;
+ break;
+ case 2:
+ b_charsize(FNT9X17);
+ term->v_char = FNT9X17_VCHAR;
+ term->h_char = FNT9X17_HCHAR;
+ 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;
+ break;
+ }
+}
+
+
+TERM_PUBLIC void
+PBM_graphics()
+{
+ int numplanes = 1;
+ unsigned int xpixels = term->xmax;
+ unsigned int ypixels = term->ymax;
+
+ /* 'set size' should not affect the size of the canvas in pixels,
+ * but versions prior to 4.2 did not have a separate 'set term size'
+ */
+ if (!PBM_explicit_size) {
+ xpixels *= xsize;
+ ypixels *= ysize;
+ }
+
+ switch (pbm_mode) {
+ case 1:
+ numplanes = 3;
+ break;
+ case 2:
+ numplanes = 4;
+ break;
+ }
+
+ /* HBB 980226: this is not the right place to do this: setfont() influences
+ * fields of the termtable entry, and therefore must be called by init()
+ * already. */
+ /* PBMsetfont(); */
+ /* rotate plot -90 degrees by reversing XMAX and YMAX and by
+ setting b_rastermode to TRUE */
+ b_makebitmap(ypixels, xpixels, numplanes);
+ b_rastermode = TRUE;
+
+ if (pbm_mode != 0)
+ b_setlinetype(0); /* solid lines */
+}
+
+
+static void
+PBM_monotext()
+{
+ register int x, j, row;
+
+ fputs("P4\n", gpoutfile);
+ fprintf(gpoutfile, "%u %u\n", b_ysize, b_xsize);
+
+ /* dump bitmap in raster mode */
+ for (x = b_xsize - 1; x >= 0; x--) {
+ row = (b_ysize / 8) - 1;
+ for (j = row; j >= 0; j--) {
+ (void) fputc((char) (*((*b_p)[j] + x)), gpoutfile);
+ }
+ }
+
+ b_freebitmap();
+}
+
+static void
+PBM_graytext()
+{
+ register int x, j, row;
+ register int i, value;
+ int mask, plane1, plane2, plane3;
+
+ fprintf(gpoutfile, "\
+P5\n\
+%u %u\n\
+%u\n",
+ b_ysize, b_xsize,
+ 255);
+
+ /* dump bitmap in raster mode */
+ for (x = b_xsize - 1; x >= 0; x--) {
+ row = (b_ysize / 8) - 1;
+ for (j = row; j >= 0; j--) {
+ mask = 0x80;
+ plane1 = (*((*b_p)[j] + x));
+ plane2 = (*((*b_p)[j + b_psize] + x));
+ plane3 = (*((*b_p)[j + b_psize + b_psize] + x));
+ for (i = 0; i < 8; i++) {
+ /* HBB: The values below are set to span the full range
+ * from 0 up to 255 in 7 steps: */
+ value = 255;
+ if (plane1 & mask)
+ value -= 36;
+ if (plane2 & mask)
+ value -= 73;
+ if (plane3 & mask)
+ value -= 146;
+ (void) fputc((char) (value), gpoutfile);
+ mask >>= 1;
+ }
+ }
+ }
+
+ b_freebitmap();
+}
+
+static void
+PBM_colortext()
+{
+ register int x, j, row;
+ register int i;
+ int mask, plane1, plane2, plane3, plane4;
+ int red, green, blue;
+
+ fprintf(gpoutfile, "P6\n\
+%u %u\n\
+%u\n",
+ b_ysize, b_xsize,
+ 255);
+
+ /* dump bitmap in raster mode */
+ for (x = b_xsize - 1; x >= 0; x--) {
+ row = (b_ysize / 8) - 1;
+ for (j = row; j >= 0; j--) {
+ mask = 0x80;
+ plane1 = (*((*b_p)[j] + x));
+ plane2 = (*((*b_p)[j + b_psize] + x));
+ plane3 = (*((*b_p)[j + b_psize + b_psize] + x));
+ plane4 = (*((*b_p)[j + b_psize + b_psize + b_psize] + x));
+ for (i = 0; i < 8; i++) {
+ red = (plane3 & mask) ? 1 : 3;
+ green = (plane2 & mask) ? 1 : 3;
+ blue = (plane1 & mask) ? 1 : 3;
+ if (plane4 & mask) {
+ red--;
+ green--;
+ blue--;
+ }
+ /* HBB: '85' is exactly 255/3, so this spans the full
+ * range of colors in three steps: */
+ (void) fputc((char) (red * 85), gpoutfile);
+ (void) fputc((char) (green * 85), gpoutfile);
+ (void) fputc((char) (blue * 85), gpoutfile);
+ mask >>= 1;
+ }
+ }
+ }
+
+ b_freebitmap();
+}
+
+TERM_PUBLIC void
+PBM_text()
+{
+ switch (pbm_mode) {
+ case 0:
+ PBM_monotext();
+ break;
+ case 1:
+ PBM_graytext();
+ break;
+ case 2:
+ PBM_colortext();
+ break;
+ }
+}
+
+
+TERM_PUBLIC void
+PBM_linetype(int linetype)
+{
+ if (linetype < -2)
+ linetype = LT_BLACK;
+
+ switch (pbm_mode) {
+ case 0:
+ b_setlinetype(linetype);
+ break;
+ case 1:
+ if (linetype >= 7)
+ linetype %= 7;
+ b_setvalue(pgm_gray[linetype + 2]);
+ break;
+ case 2:
+ if (linetype >= 9)
+ linetype %= 9;
+ b_setvalue(ppm_color[linetype + 2]);
+ break;
+ }
+}
+
+TERM_PUBLIC void
+PBM_point(unsigned int x, unsigned int y, int point)
+{
+ if (pbm_mode == 0)
+ line_and_point(x, y, point);
+ else
+ do_point(x, y, point);
+}
+
+#endif /* TERM_BODY */
+
+#ifdef TERM_TABLE
+
+TERM_TABLE_START(pbm_driver)
+ "pbm", "Portable bitmap [small medium large] [monochrome gray color]",
+ PBM_XMAX, PBM_YMAX, PBM_VCHAR,
+ PBM_HCHAR, PBM_VTIC, PBM_HTIC, PBM_options,
+ PBM_init, PBM_reset, PBM_text, null_scale,
+ PBM_graphics, b_move, b_vector, PBM_linetype,
+ b_put_text, b_text_angle, null_justify_text, PBM_point,
+ do_arrow, set_font_null,
+ 0, /* pointsize */
+ TERM_CAN_MULTIPLOT | TERM_BINARY,
+ 0, 0, b_boxfill
+TERM_TABLE_END(pbm_driver)
+
+#undef LAST_TERM
+#define LAST_TERM pbm_driver
+
+#endif /* TERM_TABLE */
+
+
+#ifdef TERM_HELP
+START_HELP(pbm)
+"1 pbm",
+"?commands set terminal pbm",
+"?set terminal pbm",
+"?set term pbm",
+"?terminal pbm",
+"?term pbm",
+"?pbm",
+" Several options may be set in the `pbm` terminal---the driver for PBMplus.",
+"",
+" Syntax:",
+" set terminal pbm {<fontsize>} {<mode>} {size <x>,<y>}",
+"",
+" where <fontsize> is `small`, `medium`, or `large` and <mode> is `monochrome`,",
+" `gray` or `color`. The default plot size is 640 pixels wide and 480 pixels",
+" high.",
+"",
+" The output of the `pbm` driver depends upon <mode>: `monochrome` produces a",
+" portable bitmap (one bit per pixel), `gray` a portable graymap (three bits",
+" per pixel) and `color` a portable pixmap (color, four bits per pixel).",
+"",
+" The output of this driver can be used with various image conversion and",
+" manipulation utilities provided by NETPBM. Based on Jef Poskanzer's",
+" PBMPLUS package, NETPBM provides programs to convert the above PBM formats",
+" to GIF, TIFF, MacPaint, Macintosh PICT, PCX, X11 bitmap and many others.",
+" Complete information is available at http://netpbm.sourceforge.net/.",
+"",
+" Examples:",
+" set terminal pbm small monochrome # defaults",
+" set terminal pbm color medium size 800,600",
+" set output '| pnmrotate 45 | pnmtopng > tilted.png' # uses NETPBM"
+END_HELP(pbm)
+#endif /* TERM_HELP */