diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2019-07-05 00:34:50 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2019-07-05 00:34:50 +0000 |
commit | 4308adfd8d6a4523f2a0f45faeae80d472b5b41b (patch) | |
tree | 7258c0984fbc4bdcf6b3d53cc1b71be0d195b11f /converter | |
parent | 0ef867669db4f32b2fc6b339983b1e81848398df (diff) | |
download | netpbm-mirror-4308adfd8d6a4523f2a0f45faeae80d472b5b41b.tar.gz netpbm-mirror-4308adfd8d6a4523f2a0f45faeae80d472b5b41b.tar.xz netpbm-mirror-4308adfd8d6a4523f2a0f45faeae80d472b5b41b.zip |
Add -linewidth
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@3649 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter')
-rw-r--r-- | converter/pbm/pbmtolps.c | 227 |
1 files changed, 131 insertions, 96 deletions
diff --git a/converter/pbm/pbmtolps.c b/converter/pbm/pbmtolps.c index dd0342bc..dcc5badd 100644 --- a/converter/pbm/pbmtolps.c +++ b/converter/pbm/pbmtolps.c @@ -4,9 +4,13 @@ * generate a (device dependent) picture which will be imaged * much faster. * - * The Postscript path length is constrained to be less that 1000 + * The Postscript path length is constrained to be at most 1000 * points so that no limits are overrun on the Apple Laserwriter - * and (presumably) no other printers. + * and (presumably) no other printers. The typical limit is 1500. + * See "4.4 Path Construction" and "Appendix B: Implementation Limits" + * in: PostScript Language Reference Manual + * https://www.adobe.com/content/dam/acom/en/devnet/actionscript/ + * articles/psrefman.pdf * * To do: * make sure encapsulated format is correct @@ -19,125 +23,143 @@ * University of British Columbia */ -#include <string.h> -#include <stdio.h> - +#include "pm_c_util.h" +#include "mallocvar.h" #include "nstring.h" +#include "shhopt.h" #include "pbm.h" -static int prev_white = -1; -static int prev_black = -1; -static char cmd = '\0'; -static int pointcount = 2; +static float const MaxDPI = 5000; +static float const MinDPI = 10; +static unsigned int const MaxPathPoints = 1000; + + +struct CmdlineInfo { + /* All the information the user supplied in the command line, in a form + easy for the program to use. + */ + const char * inputFileName; /* File name of input file */ + unsigned int inputFileSpec; /* Input file name specified */ + float lineWidth; /* Line width, if specified */ + unsigned int lineWidthSpec; /* Line width specified */ + float dpi; /* Resolution in DPI, if specified */ + unsigned int dpiSpec; /* Resolution specified */ +}; + -#ifdef RUN -static int run = 1; -#endif -static char -morepoints(char cmd, int howmany_pbmtolps) { - pointcount += 2; - if (pointcount > 1000) { - pointcount = 2; - cmd += 'm' - 'a'; +static void +parseCommandLine(int argc, + const char ** const argv, + struct CmdlineInfo * const cmdlineP) { +/*---------------------------------------------------------------------------- + Parse program command line described in Unix standard form by argc + and argv. Return the information in the options as *cmdlineP. +-----------------------------------------------------------------------------*/ + optEntry * option_def; /* malloc'ed */ + /* Instructions to OptParseOptions3 on how to parse our options. */ + optStruct3 opt; + + unsigned int option_def_index; + + MALLOCARRAY_NOFAIL(option_def, 100); + + option_def_index = 0; /* incremented by OPTENTRY */ + OPTENT3(0, "linewidth", OPT_FLOAT, &cmdlineP->lineWidth, + &cmdlineP->lineWidthSpec, 0); + OPTENT3(0, "dpi", OPT_FLOAT, &cmdlineP->dpi, + &cmdlineP->dpiSpec, 0); + + opt.opt_table = option_def; + opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ + opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + + pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); + /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + + if (argc-1 < 1) + cmdlineP->inputFileName = "-"; + else { + if (argc-1 > 1) + pm_error("Program takes zero or one argument (filename). You " + "specified %d", argc-1); + else + cmdlineP->inputFileName = argv[1]; } - return(cmd); + + if (cmdlineP->inputFileName[0] == '-' && + cmdlineP->inputFileName[1] == '\0') + cmdlineP->inputFileSpec = FALSE; + else + cmdlineP->inputFileSpec = TRUE; + + if (cmdlineP->dpiSpec == FALSE) + cmdlineP->dpi = 300; + + free(option_def); } static void -addstrip(int const white, - int const black) { - - if (cmd) { -#ifdef RUN - if (white == prev_white && black == prev_black) - run++; - else { - if (run == 1) -#endif - printf("%d %d %c ", - prev_black, prev_white, morepoints(cmd, 2)); -#ifdef RUN - else - /* of course, we need to give a new command */ - printf("%d %d %d %c ", - prev_white, prev_black, run, - morepoints(cmd + 'f' - 'a', 2 * run)); - run = 1; - } -#endif - } +validateLineWidth(float const sc_cols, + float const sc_rows, + float const lineWidth) { - prev_white = white; - prev_black = black; - cmd = 'a'; + if (lineWidth >= sc_cols || lineWidth >= sc_rows) + pm_error("Absurdly large -linewidth value (%f)", lineWidth); } static void -nextline(void) { - /* need to check run, should have an outcommand */ - if (cmd) - printf("%d %d %c\n", prev_black, prev_white, morepoints('c', 3)); - else - printf("%c\n", morepoints('b', 1)); - cmd = '\0'; +validateDpi(float const dpi) { + if (dpi > MaxDPI || dpi < MinDPI) + pm_error("Specified DPI value out of range (%f)", dpi); } int -main(int argc, char ** argv) { +main(int argc, const char *argv[]) { FILE* fp; bit* bits; - int row; - int col; - int rows; - int cols; - int format; - int white; - int black; - const char* name; - float dpi = 300.0; + int row; + int col; + int rows; + int cols; + int format; + int white; + int black; float sc_rows; float sc_cols; - int i; - const char* const usage = "[ -dpi n ] [ pbmfile ]"; + struct CmdlineInfo cmdline; + const char* psName; + unsigned int pointCnt; + pm_proginit(&argc, argv); - pbm_init(&argc, argv); + parseCommandLine(argc, argv, &cmdline); + + if (cmdline.dpi) + validateDpi(cmdline.dpi); - i = 1; - if (i < argc && streq(argv[i], "-dpi")) { - if (i == argc - 1) - pm_usage(usage); - sscanf(argv[i + 1], "%f", &dpi); - i += 2; - } + fp = pm_openr(cmdline.inputFileName); + pbm_readpbminit(fp, &cols, &rows, &format); - if (i < argc - 1) - pm_usage(usage); + sc_rows = (float) rows / cmdline.dpi * 72.0; + sc_cols = (float) cols / cmdline.dpi * 72.0; + + if (cmdline.lineWidthSpec) + validateLineWidth(sc_cols, sc_rows, cmdline.lineWidth); - if (i == argc) { - name = "noname"; - fp = stdin; - } else { - name = argv[i]; - fp = pm_openr(name); - } - pbm_readpbminit(fp, &cols, &rows, &format); bits = pbm_allocrow(cols); - - sc_rows = (float)rows / dpi * 72.0; - sc_cols = (float)cols / dpi * 72.0; + psName = cmdline.inputFileSpec ? cmdline.inputFileName : "noname"; puts("%!PS-Adobe-2.0 EPSF-2.0"); puts("%%Creator: pbmtolps"); - printf("%%%%Title: %s\n", name); + printf("%%%%Title: %s\n", psName); printf("%%%%BoundingBox: %d %d %d %d\n", (int)(305.5 - sc_cols / 2.0), (int)(395.5 - sc_rows / 2.0), @@ -148,29 +170,42 @@ main(int argc, char ** argv) { puts("gsave"); printf("%f %f translate\n", 306.0 - sc_cols / 2.0, 396.0 + sc_rows / 2.0); - printf("72 %f div dup neg scale\n", dpi); + printf("72 %f div dup neg scale\n", cmdline.dpi); + if (cmdline.lineWidthSpec) + printf("%f setlinewidth\n", cmdline.lineWidth); puts("/a { 0 rmoveto 0 rlineto } def"); - puts("/b { 0 row 1 add dup /row exch def moveto } def"); - puts("/c { a b } def"); - puts("/m { currentpoint stroke newpath moveto a } def"); - puts("/n { currentpoint stroke newpath moveto b } def"); - puts("/o { currentpoint stroke newpath moveto c } def"); - puts("/row 0 def"); + puts("/m { currentpoint stroke newpath moveto } def"); puts("newpath 0 0 moveto"); + pointCnt = 0; for (row = 0; row < rows; row++) { + bool firstRun = TRUE; /* Initial value */ + pbm_readpbmrow(fp, bits, cols, format); - /* output white-strip+black-strip sequences */ + /* output white-strip + black-strip sequences */ for (col = 0; col < cols; ) { + for (white = 0; col < cols && bits[col] == PBM_WHITE; col++) white++; for (black = 0; col < cols && bits[col] == PBM_BLACK; col++) black++; - if (black != 0) - addstrip(white, black); + if (black != 0) { + if (pointCnt > MaxPathPoints) { + printf("m "); + pointCnt = 0; + } + + if (firstRun == TRUE) { + printf ("%d %d moveto %d 0 rlineto\n", white, row, black); + firstRun = FALSE; + } + else + printf("%d %d a\n", black, white); + + pointCnt += 2; + } } - nextline(); } puts("stroke grestore showpage"); puts("%%Trailer"); |