📄 postmd.c
字号:
case 'y': /* and vertically on the page */ fprintf(stdout, "/yoffset %s def\n", optarg); break; case 'A': /* force job accounting */ case 'J': if ( (fp_acct = fopen(optarg, "a")) == NULL ) error(FATAL, "can't open accounting file %s", optarg); break; case 'C': /* copy file straight to output */ if ( cat(optarg) == FALSE ) error(FATAL, "can't read %s", optarg); break; case 'E': /* text font encoding */ fontencoding = optarg; break; case 'L': /* PostScript prologue file */ prologue = optarg; break; case 'P': /* PostScript pass through */ fprintf(stdout, "%s\n", optarg); break; case 'R': /* special global or page level request */ saverequest(optarg); break; case 'D': /* debug flag */ debug = ON; break; case 'I': /* ignore FATAL errors */ ignore = ON; break; case '?': /* don't understand the option */ error(FATAL, ""); break; default: /* don't know what to do for ch */ error(FATAL, "missing case for option %c\n", ch); break; } /* End switch */ } /* End while */ argc -= optind; /* get ready for non-option args */ argv += optind;} /* End of options *//*****************************************************************************/setup(){/* * * Handles things that must be done after the options are read but before the * input files are processed. * */ writerequest(0, stdout); /* global requests eg. manual feed */ setencoding(fontencoding); fprintf(stdout, "setup\n"); if ( formsperpage > 1 ) { if ( cat(formfile) == FALSE ) error(FATAL, "can't read %s", formfile); fprintf(stdout, "%d setupforms\n", formsperpage); } /* End if */ fprintf(stdout, "%s", ENDSETUP);} /* End of setup *//*****************************************************************************/arguments(){/* * * Makes sure all the non-option command line arguments are processed. If we get * here and there aren't any arguments left, or if '-' is one of the input files * we'll process stdin. * */ if ( argc < 1 ) matrix(); else { /* at least one argument is left */ while ( argc > 0 ) { matrixname = *argv; if ( strcmp(*argv, "-") == 0 ) { fp_in = stdin; matrixname = "pipe.end"; } else if ( (fp_in = fopen(*argv, "r")) == NULL ) error(FATAL, "can't open %s", *argv); matrix(); if ( fp_in != stdin ) fclose(fp_in); argc--; argv++; } /* End while */ } /* End else */} /* End of arguments *//*****************************************************************************/done(){/* * * Finished with all the input files, so mark the end of the pages, make sure the * last page is printed, and restore the initial environment. * */ fprintf(stdout, "%s", TRAILER); fprintf(stdout, "done\n"); fprintf(stdout, "%s %d\n", PAGES, printed); if ( temp_file != NULL ) unlink(temp_file);} /* End of done *//*****************************************************************************/account(){/* * * Writes an accounting record to *fp_acct provided it's not NULL. Accounting * is requested using the -A or -J options. * */ if ( fp_acct != NULL ) fprintf(fp_acct, " print %d\n copies %d\n", printed, copies);} /* End of account *//*****************************************************************************/matrix(){ int count; /* pattern repeats this many times */ long total; /* expect this many patterns *//* * * Reads a matrix from *fp_in, translates it into a PostScript gray scale image, * and writes the result on stdout. For now only one matrix is allowed per input * file. Matrix elements are floating point numbers arranged in row major order * in the input file. In addition each input file may contain an optional header * that defines special things like the dimension of the matrix, a window into * the matrix that will be displayed, and an interval list. * * If we're reading from stdin we first make a copy in a temporary file so we can * can properly position ourselves after we've looked for the header. Originally * wasn't always making a copy of stdin, but I've added a few things to what's * accepted in the header and this simplifies the job. An alternative would be * to always require a header and mark the end of it by some string. Didn't like * that approach much - may fix things up later. * */ if ( fp_in == stdin ) /* make a copy so we can seek etc. */ copystdin(); rows = dfltrows; /* new dimensions for the next matrix */ columns = dfltcols; buildilist(interval); /* build the default ilist[] */ addcolormap(colormap); /* add the colormap - if not NULL */ setwindow(window); /* and setup the initial matrix window */ nxtstat = dostats; /* want statistics? */ getheader(); /* matrix dimensions at the very least */ dimensions(); /* make sure we have the dimensions etc. */ patcount = 0; total = rows * columns; eptr = rptr + (wlist[2] - wlist[0] + 1); redirect(++page); fprintf(fp_out, "%s %d %d\n", PAGE, page, printed+1); fprintf(fp_out, "/saveobj save def\n"); writerequest(printed+1, fp_out); fprintf(fp_out, "%d %d bitmap\n", wlist[2] - wlist[0] + 1, wlist[3] - wlist[1] + 1); while ( patcount != total && fscanf(fp_in, "%f", &element) != EOF ) { if ( inwindow() ) *rptr++ = mapfloat(element); if ( ++patcount % columns == 0 ) if ( inrange() ) putrow(); } /* End while */ if ( total != patcount ) error(FATAL, "matrix format error"); labelmatrix(); if ( fp_out == stdout ) printed++; fprintf(fp_out, "showpage\n"); fprintf(fp_out, "saveobj restore\n"); fprintf(fp_out, "%s %d %d\n", ENDPAGE, page, printed);} /* End of matrix *//*****************************************************************************/copystdin(){ int fd_out; /* for the temporary file */ int fd_in; /* for stdin */ int buf[512]; /* buffer for reads and writes */ int count; /* number of bytes put in buf *//* * * If we're reading the matrix from stdin and the matrix dimension isn't set by * a dimension statement at the beginning of the file we'll copy stdin to a * temporary file and reset *fp_in so reads come from the temp file. Simplifies * reading the header (if present), but is expensive. * */ if ( temp_file != NULL ) /* been here already */ unlink(temp_file); if ( (temp_file = tempnam(temp_dir, "post")) == NULL ) error(FATAL, "can't generate temp file name"); if ( (fd_out = creat(temp_file, 0660)) == -1 ) error(FATAL, "can't create %s", temp_file); fd_in = fileno(stdin); while ( (count = read(fd_in, buf, sizeof(buf))) > 0 ) if ( write(fd_out, buf, count) != count ) error(FATAL, "error writing to %s", temp_file); close(fd_out); if ( (fp_in = fopen(temp_file, "r")) == NULL ) error(FATAL, "can't open %s", temp_file);} /* End of copystdin *//*****************************************************************************/getheader(){ char buf[512]; /* temporary string space */ char *cmap = NULL; /* remember header colormap list */ long pos; /* for seeking back to first element *//* * * Looks for the optional header information at the beginning of the input file, * reads it if it's there, and sets *fp_in to be just past the header. That should * be the beginning of the matrix element list. The recognized header keywords are * dimension, interval, colormap (or grayscale), window, name, and statistics. All * are optional, but may be useful in a spooling environment when the user doesn't * doesn't actually run the translator. * * The dimension statement specifies the number of rows and columns. For example * either of the following two lines define a 50 by 50 element matrix, * * dimension 50 * dimension 50x50 * * The first integer is the number of rows and the second, if given, is the number * of columns. If columns are missing from the dimension statement we assume the * matrix is square. * * interval can be used to redefine the interval list used for mapping floating * point numbers into integers in the range 0 to 254. The string following the * interval keyword has the same format as the -i option. For example to set the * interval list to -1, 0, and 1 you can add the line, * * interval -1,0,1 * * The numbers are floats given in increasing order, and separated by commas or * blanks. The last interval list in a header takes precedence. * * colormap can be used to redefine the grayscale list. The string following * the colormap keyword has the same format as the -g option. For example * * colormap 0,50,100,150,200,250 * or grayscale 0,50,100,150,200,250 * * The window keyword can be used to select a submatrix. The numbers following * window are the upper left and lower right matix coordinates. May not be * implemented yet but shouldn't be difficult. For example * * window 10 10 40 40 * * selects the submatrix with corners at (10, 10) and (40, 40). The edges of the * window are included in the display. * * The name keyword can be used to define the title of the display. For example, * * name Plot Of Matrix 1 * * prints the string "Plot Of Matrix 1" at the top of the page. Everything up to * the next newline is taken as the name string. * */ pos = ftell(fp_in); while ( fscanf(fp_in, "%s", buf) != EOF ) { if ( strncmp(buf, "dimension", strlen("dimension")) == 0 ) fscanf(fp_in, "%dx%d", &rows, &columns); else if ( strncmp(buf, "window", strlen("window")) == 0 ) { fgets(buf, sizeof(buf), fp_in); setwindow(buf); } else if ( strncmp(buf, "name", strlen("name")) == 0 ) { fgets(buf, sizeof(buf), fp_in); matrixname = savestring(buf); } else if ( strncmp(buf, "colormap", strlen("colormap")) == 0 ) { fgets(buf, sizeof(buf), fp_in); cmap = savestring(buf); } else if ( strncmp(buf, "grayscale", strlen("grayscale")) == 0 ) { fgets(buf, sizeof(buf), fp_in); cmap = savestring(buf); } else if ( strncmp(buf, "interval", strlen("interval")) == 0 ) { fgets(buf, sizeof(buf), fp_in); buildilist(buf); } else if ( strncmp(buf, "statistics", strlen("statistics")) == 0 ) { fscanf(fp_in, "%s", buf); if ( strcmp(buf, "on") == 0 || strcmp(buf, "ON") == 0 ) nxtstat = ON; else nxtstat = OFF; } else break; pos = ftell(fp_in); } /* End while */ addcolormap(cmap); /* must happen last */ fseek(fp_in, pos, 0); /* back to the start of the matrix */} /* End of getheader *//*****************************************************************************/dimensions(){ char buf[100]; /* temporary storage for the elements */ long count = 0; /* number of elements in the matrix */ long pos; /* matrix elements start here *//* * * Need to know the dimensions of the matrix before we can go any farther. If * rows and columns are still 0 we'll read the entire input file, starting from * the current position, count the number of elements, take the square root of it, * and use it as the number of rows and columns. Then we seek back to the start * of the real matrix, make sure columns is set, and allocate enough memory for * storing each raster line. After we're certain we've got the number of rows and * columns we check the window coordinates, and if they're not legitimate they're * reset to cover the entire matrix.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -