void set_paper_size(const char *paper_name) { const struct paper *paper = get_paper(paper_name); if (paper) { width = paperpswidth(paper); height = paperpsheight(paper); } }
void dumppaperinfo (void) { const struct paper *ppinfo; ppinfo = paperfirst(); while (ppinfo && papername(ppinfo)) { double wd, ht; wd = paperpswidth (ppinfo); ht = paperpsheight(ppinfo); fprintf(stdout, "%s: %.2f %.2f (%.2fmm %.2fmm)\n", papername(ppinfo), wd, ht, 25.4 * wd / 72.0, 25.4 * ht / 72.0); ppinfo = papernext(ppinfo); } }
int paper_size (const char *paper_name, double *width, double *height) { const struct paper *pi; do_init (); if (!(pi = paperinfo (paper_name ? paper_name : default_paper))) return 0; *width = paperpswidth (pi); *height = paperpsheight (pi); return 1; }
int main(int argc, char *argv[]) { double scale, rscale; /* page scale */ double waste, rwaste; /* amount wasted */ double vshift, hshift; /* page centring shifts */ int rotate; double inwidth = -1; double inheight = -1; off_t sizeheaders[20]; /* headers to remove */ PageSpec *specs; int opt; const struct paper *paper = NULL; set_paper_size(NULL); vshift = hshift = 0; rotate = 0; verbose = 1; program = *argv; while((opt = getopt(argc, argv, "qw:h:p:W:H:P:")) != EOF) { switch(opt) { case 'q': /* quiet */ verbose = 0; break; case 'w': /* page width */ width = singledimen(optarg); break; case 'h': /* page height */ height = singledimen(optarg); break; case 'p': /* paper type */ if ( (paper = paperinfo(optarg)) != NULL ) { width = paperpswidth(paper); height = paperpsheight(paper); } else message(FATAL, "paper size '%s' not recognised\n", optarg); break; case 'W': /* input page width */ inwidth = singledimen(optarg); break; case 'H': /* input page height */ inheight = singledimen(optarg); break; case 'P': /* input paper type */ if ( (paper = paperinfo(optarg)) != NULL ) { inwidth = paperpswidth(paper); inheight = paperpsheight(paper); } else message(FATAL, "paper size '%s' not recognised\n", optarg); break; case 'v': /* version */ default: usage(); } } infile = stdin; outfile = stdout; /* Be defensive */ if((argc - optind) < 0 || (argc - optind) > 2) usage(); if (optind != argc) { /* User specified an input file */ if ((infile = fopen(argv[optind], "rb")) == NULL) message(FATAL, "can't open input file %s\n", argv[optind]); optind++; } if (optind != argc) { /* User specified an output file */ if ((outfile = fopen(argv[optind], "wb")) == NULL) message(FATAL, "can't open output file %s\n", argv[optind]); optind++; } if (optind != argc) usage(); if ((infile=seekable(infile))==NULL) message(FATAL, "can't seek input\n"); if (width <= 0 || height <= 0) message(FATAL, "output page width and height must be set\n"); scanpages(sizeheaders); if (inwidth <= 0 || inheight <= 0) message(FATAL, "input page width and height must be set\n"); /* try normal orientation first */ scale = MIN(width/inwidth, height/inheight); waste = (width-scale*inwidth)*(width-scale*inwidth) + (height-scale*inheight)*(height-scale*inheight); hshift = (width - inwidth*scale)/2; vshift = (height - inheight*scale)/2; /* try rotated orientation */ rscale = MIN(height/inwidth, width/inheight); rwaste = (height-scale*inwidth)*(height-scale*inwidth) + (width-scale*inheight)*(width-scale*inheight); if (rwaste < waste) { double tmp = width; scale = rscale; hshift = (width + inheight*scale)/2; vshift = (height - inwidth*scale)/2; rotate = 1; width = height; height = tmp; } width /= scale; height /= scale; /* now construct specification list and run page rearrangement procedure */ specs = newspec(); if (rotate) { specs->rotate = 90; specs->flags |= ROTATE; } specs->pageno = 0; specs->scale = scale; specs->flags |= SCALE; specs->xoff = hshift; specs->yoff = vshift; specs->flags |= OFFSET; pstops_write(1, 1, 0, specs, 0.0, sizeheaders); /* do page rearrangement */ return 0; }
/* Actually save the PostScript data to the file stream: */ int do_ps_save(FILE * fi, // const char *restrict const fname, const char * fname, SDL_Surface * surf, char * pprsize, int is_pipe) { const struct paper * ppr; int img_w = surf->w; int img_h = surf->h; int r_img_w, r_img_h; int ppr_w, ppr_h; int x, y; float tlate_x, tlate_y; int cur_line_len; int plane; Uint8 r, g, b; char buf[256]; Uint32(*getpixel) (SDL_Surface *, int, int) = getpixels[surf->format->BytesPerPixel]; int printed_img_w, printed_img_h; time_t t = time(NULL); int rotate; float scale; /* Determine paper size: */ paperinit(); // FIXME: Should we do this at startup? -bjk 2007.06.25 if (pprsize == NULL) { /* User did not request a specific paper size (on command-line or in config file), ask the system. It will return either their $PAPER env. var., the value from /etc/papersize, or NULL: */ pprsize = (char *) systempapername(); if (pprsize == NULL) { /* No setting, env. var. or /etc/ file; use the default! */ pprsize = (char *) defaultpapername(); #ifdef DEBUG printf("Using default paper\n"); #endif } #ifdef DEBUG else { printf("Using system paper\n"); } #endif } #ifdef DEBUG else { printf("Using user paper\n"); } #endif #ifdef DEBUG printf("Using paper size: %s\n", pprsize); #endif /* Determine attributes of paper of the size chosen/determined: */ ppr = paperinfo(pprsize); ppr_w = paperpswidth(ppr); ppr_h = paperpsheight(ppr); #ifdef DEBUG printf("Paper is %d x %d (%.2f\" x %.2f\")\n", ppr_w, ppr_h, (float) ppr_w / 72.0, (float) ppr_h / 72.0); #endif paperdone(); // FIXME: Should we do this at quit? -bjk 2007.06.25 /* Determine whether it's best to rotate the image: */ if ((ppr_w >= ppr_h && img_w >= img_h) || (ppr_w <= ppr_h && img_w <= img_h)) { rotate = 0; r_img_w = img_w; r_img_h = img_h; } else { rotate = 1; r_img_w = img_h; r_img_h = img_w; } #ifdef DEBUG printf("Image is %d x %d\n", img_w, img_h); printf("Rotated? %s\n", rotate ? "yes" : "no"); printf("Will print %d x %d pixels\n", r_img_w, r_img_h); #endif /* Determine scale: */ scale = my_min(((float) (ppr_w - (MARGIN * 2)) / (float) r_img_w), ((float) (ppr_h - (MARGIN * 2)) / (float) r_img_h)); printed_img_w = r_img_w * scale; printed_img_h = r_img_h * scale; #ifdef DEBUG printf("Scaling image by %.2f (to %d x %d)\n", scale, printed_img_w, printed_img_h); #endif // FIXME - doesn't seem to center well -bjk 2007.06.25 tlate_x = (ppr_w - printed_img_w) / 2; tlate_y = (ppr_h - printed_img_h) / 2; /* Based off of output from "pnmtops", Tux Paint 0.9.15 thru 0.9.17 CVS as of June 2007, and Adobe Systems Incorporated's 'PostScript(r) Language Reference, 3rd Ed.' */ /* Begin PostScript output with some useful meta info in comments: */ fprintf(fi, "%%!PS-Adobe-2.0 EPSF-2.0\n"); // we need LanguageLevel2 for color fprintf(fi, "%%%%Title: (%s)\n", fname); strftime(buf, sizeof buf - 1, "%a %b %e %H:%M:%S %Y", localtime(&t)); fprintf(fi, "%%%%CreationDate: (%s)\n", buf); fprintf(fi, "%%%%Creator: (Tux Paint " VER_VERSION ", " VER_DATE ")\n"); fprintf(fi, "%%%%Pages: 1\n"); fprintf(fi, "%%%%BoundingBox: 0 0 %d %d\n", (int) (ppr_w + 0.5), (int) (ppr_h + 0.5)); fprintf(fi, "%%%%EndComments\n"); /* Define a 'readstring' routine and 'picstr' routines for RGB: */ fprintf(fi, "/readstring {\n"); fprintf(fi, " currentfile exch readhexstring pop\n"); fprintf(fi, "} bind def\n"); fprintf(fi, "/rpicstr %d string def\n", img_w); fprintf(fi, "/gpicstr %d string def\n", img_w); fprintf(fi, "/bpicstr %d string def\n", img_w); fprintf(fi, "%%%%EndProlog\n"); fprintf(fi, "%%%%Page: 1 1\n"); fprintf(fi, "<< /PageSize [ %d %d ] /ImagingBBox null >> setpagedevice\n", ppr_w, ppr_h); fprintf(fi, "gsave\n"); /* 'translate' moves the user space origin to a new position with respect to the current page, leaving the orientation of the axes and the unit lengths unchanged. */ fprintf(fi, "%d.%02d %d.%02d translate\n", f2int(tlate_x), f2dec(tlate_x), f2int(tlate_y), f2dec(tlate_y)); /* 'scale' modifies the unit lengths independently along the current x and y axes, leaving the origin location and the orientation of the axes unchanged. */ fprintf(fi, "%d.%02d %d.%02d scale\n", f2int(printed_img_w), f2dec(printed_img_w), f2int(printed_img_h), f2dec(printed_img_h)); /* Rotate the image */ if (rotate) fprintf(fi, "0.5 0.5 translate 90 rotate -0.5 -0.5 translate\n"); fprintf(fi, "%d %d 8\n", img_w, img_h); fprintf(fi, "[ %d 0 0 %d 0 %d ]\n", img_w, -img_h, img_h); fprintf(fi, "{ rpicstr readstring }\n"); fprintf(fi, "{ gpicstr readstring }\n"); fprintf(fi, "{ bpicstr readstring }\n"); fprintf(fi, "true 3\n"); fprintf(fi, "colorimage\n"); cur_line_len = 0; for (y = 0; y < img_h; y++) { for (plane = 0; plane < 3; plane++) { for (x = 0; x < img_w; x++) { SDL_GetRGB(getpixel(surf, x, y), surf->format, &r, &g, &b); fprintf(fi, "%02x", (plane == 0 ? r : (plane == 1 ? g : b))); cur_line_len++; if (cur_line_len >= 30) { fprintf(fi, "\n"); cur_line_len = 0; } } } } fprintf(fi, "\n"); fprintf(fi, "grestore\n"); fprintf(fi, "showpage\n"); fprintf(fi, "%%%%Trailer\n"); fprintf(fi, "%%%%EOF\n"); if (!is_pipe) { fclose(fi); return 1; } else { pid_t child_pid, w; int status; child_pid = pclose(fi); /* debug */ /* printf("pclose returned %d\n", child_pid); fflush(stdout); printf("errno = %d\n", errno); fflush(stdout); */ if (child_pid < 0 || (errno != 0 && errno != EAGAIN)) { /* FIXME: This right? */ return 0; } else if (child_pid == 0) { return 1; } do { w = waitpid(child_pid, &status, 0); /* debug */ /* if (w == -1) { perror("waitpid"); exit(EXIT_FAILURE); } if (WIFEXITED(status)) { printf("exited, status=%d\n", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf("killed by signal %d\n", WTERMSIG(status)); } else if (WIFSTOPPED(status)) { printf("stopped by signal %d\n", WSTOPSIG(status)); } else if (WIFCONTINUED(status)) { printf("continued\n"); } */ } while (w != -1 && !WIFEXITED(status) && !WIFSIGNALED(status)); if (WIFEXITED(status) && WEXITSTATUS(status) != 0) /* Not happy exit */ return 0; return 1; } }