Article View: comp.lang.postscript
Article #6610poster (Scale 1page postscript files)
From: Ger Timmens
Date: Fri, 08 Jan 1993 14:21
Date: Fri, 08 Jan 1993 14:21
416 lines
13583 bytes
13583 bytes
This simple c programs poster is a generic PS scaling program,
just 'sh' this file, and compile poster.c with 'cc -O -c poster.c -o poster'.
Have fun,
#!/bin/sh
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 01/08/1993 14:18 UTC by ger@triton
# Source directory /Userspace1/ger/src/poster
#
# existing files will NOT be overwritten unless -c is specified
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 2774 -rw-r--r-- README
# 41 -rw-r--r-- bool.h
# 7499 -rw-r--r-- poster.c
#
# ============= README ==============
if test -f 'README' -a X"$1" != X"-c"; then
echo 'x - skipping README (File already exists)'
else
echo 'x - extracting README (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'README' &&
Poster - a generic PS scaling program
X
Known restrictions:
1. It only works with one-pager. Don't try multiple page document with this.
2. Always produce 7.5"x10" tiles with crop marks and grid # at lower right.
3. Won't best fit to use minimum number of tiles by intellegent rotation.
X (Enhancements are welcome, make sure you debug it before sending your fix
X to me! )
4. It treats Landscape mode page the same way as Portrait page. The printing
X is okay, but the width/height specification and grid numbering is rotated.
X (use it on a Landscape page and look at the grid #, you'll see what I mean)
5. It uses brute force, it outputs the whole file once for each tile produced.
X If you're printing a 1/4 Megabyte PS file on 4 tiles, you are creating a
X file over one megabyte in size and takes 4 times as long to print.
6. If no BoundingBox info is found, assumes 0 0 612 792. Will not look for
X BoundingBox info beyond the first %%EndComments line (try to prevent getting
X the wrong one from other imbedded images.)
7. Only leave 1/2" inch border. If you need extra spacing around the image,
X you should alter the BoundingBox info yourself.
8. Works well with all my PS images. Yours? Good luck! :-)
X
Compilation:
X cc -o poster poster.c
X
Usage:
X poster ps-file width height [ row col ]
X
X ps-file is your well behaving PS program.
X width and height is the output dimension expressed in inches.
X Since the tiles are 7.5"x10", using 15 20 will usually
X produces 2x2 (4) tiles. Depends on the aspect ratio
X of the BoundingBox, unneeded tiles will not be output.
X The program will fit the image in the area specified
X without altering the aspect ratio. Hence using 15 10000
X means you don't care about the height. It will create
X as many tiles as needed to fit the width.
X row and col is the grid that you want to output. If not specified,
X all tiles are output in the same stream. This is useful in case
X some tiles are demaged by paper jam. Also if your PS program is
X big and sending it out multiple times in one job is impossible,
X then you can use a loop to output the tiles in separate jobs, e.g.
X
X foreach i (1 2 3 4)
X foreach j (1 2 3 4)
X poster ps-file 30 40 $i $j | lpr -Pps
X end
X end
X
X will print all 16 tiles (30"x40" output) to the printer.
X
Advice:
1 print the poster only at off hours.
2 Enough overlapping of image is produced to assist easy fitting.
3 Paste every other tiles together in a "checker-board" manner (leave
X the borders intact, only cut out the corners near the crop marks)
X and then clip the rest of the tiles along the crop marks and then paste
X the tiles on the "checker-board". The borders that you left behind in
X the previous step now provide nice backing for the rest of the tiles.
SHAR_EOF
chmod 0644 README ||
echo 'restore of README failed'
Wc_c="`wc -c < 'README'`"
test 2774 -eq "$Wc_c" ||
echo 'README: original size 2774, current size' "$Wc_c"
fi
# ============= bool.h ==============
if test -f 'bool.h' -a X"$1" != X"-c"; then
echo 'x - skipping bool.h (File already exists)'
else
echo 'x - extracting bool.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'bool.h' &&
int BOOL;
#define TRUE 0
#define FALSE 1
SHAR_EOF
chmod 0644 bool.h ||
echo 'restore of bool.h failed'
Wc_c="`wc -c < 'bool.h'`"
test 41 -eq "$Wc_c" ||
echo 'bool.h: original size 41, current size' "$Wc_c"
fi
# ============= poster.c ==============
if test -f 'poster.c' -a X"$1" != X"-c"; then
echo 'x - skipping poster.c (File already exists)'
else
echo 'x - extracting poster.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'poster.c' &&
/*
# poster.c - a generic PS scaling program
# This program outputs a PostScript page to a given size, create tiles if necessary.
# each tile will be 7.5" by 10" with crop marks.
#
######################
# CopyRight Notice: #
######################
#
# Feel free to distribute or use, provided that nothing is changed.
# Please send comments, bug fixes to pyramid!daisy!cplai
#
# Author: C.P. Lai (All rights reserved)
# Creation Date: Dec 22, 1987
# Modification History:
# by C.P. Lai on Aug 18, 1989 for BoundingBox Handling.
#
#
# Usage: Poster ps-file width height [row col] | lpr -Pps
# where ps-file is the file name of the PostScript page
# width and height are the size in inches
# row and col are option if only one tile is to be printed.
# default is to print all tiles
*/
X
#include <stdio.h>
#include "bool.h"
#define BUFSIZE 512
/* tile size */
#define PAGEW 7.5
#define PAGEH 10.0
X
main (argc, argv)
int argc;
char *argv[];
{
char *pagename;
float width, height;
int row, col, llx, lly, urx, ury;
X
X row = col = 0;
X /* accepts only two command formats */
X if (!(argc == 4 || argc == 6)) usage(argv[0]);
X pagename = argv[1];
X if (sscanf (argv[2], "%f", &width) != 1) usage(argv[0]);
X if (sscanf (argv[3], "%f", &height) != 1) usage(argv[0]);
X if (argc == 6) {
X if (sscanf (argv[4], "%d", &row) != 1) usage(argv[0]);
X if (sscanf (argv[5], "%d", &col) != 1) usage(argv[0]);
X if (row<1 || col<1) usage(argv[0]);
X }
X getBoundingBox (pagename, &llx, &lly, &urx, &ury);
X printposter (pagename, llx, lly, urx, ury, width, height, row, col);
X
X exit (0);
}
X
/**************************************/
/* output usage message and terminate */
/**************************************/
usage (prog_name)
char *prog_name;
{
X fprintf (stderr, "Usage:\t%s ps-file width height [row col]\n", prog_name);
X fprintf (stderr, "\twhere ps-file is the file name of the PostScript page\n");
X fprintf (stderr, "\twidth and height are the size in inches\n");
X fprintf (stderr, "\trow and col are option if only one tile is to be printed.\n");
X fprintf (stderr, "\tdefault is to print all tiles.\n");
X exit (1);
}
X
/*********************************************/
/* output the poster, create tiles if needed */
/*********************************************/
printposter (pagename, llx, lly, urx, ury, width, height, row, col)
char *pagename;
int llx, lly, urx, ury, row, col;
float width, height;
{
int nrow, ncol, imagew, imageh;
float xscale, yscale, scale;
X
X imagew = urx - llx;
X imageh = ury - lly;
X xscale = (width * 72) / imagew;
X yscale = (height * 72) / imageh;
X scale = (xscale<yscale)?xscale:yscale;
X
X /* adjust actual width and height based on aspect ratio */
X width = imagew * scale / 72;
X height = imageh * scale / 72;
X
X ncol = (int) (width / PAGEW);
X /* add one column if exceed by one user space unit */
X if ((width-(ncol*PAGEW))*72 > 1) { ncol++; }
X nrow = (int) (height / PAGEH);
X /* add one row if exceed by one user space unit */
X if ((height-(nrow*PAGEH))*72 > 1) { nrow++; }
X
X if (row>nrow || col>ncol) {
X fprintf (stderr, "The image does not fall on grid (%d,%d)\n", row, col);
X exit (1);
X }
X
X printf ("%%!PS\t");
X if (row == 0 || col == 0)
X printf ("All grids ");
X else
X printf ("Grid (%d,%d) ", row, col);
X printf ("of poster %s in %dx%d tiles at %f scale\n",
X pagename, nrow, ncol, scale);
X
X printprolog (scale, llx, lly);
X if (row == 0 || col == 0) {
X /* all tile */
X for (row = 1; row <= nrow; row++)
X for (col = 1; col <= ncol; col++)
X tile (pagename, row, col);
X } else tile (pagename, row, col);
X printf ("%% End of Poster %s\n", pagename);
X return;
}
X
/*******************************************************/
/* output PS prolog of the scaling and tiling routines */
/*******************************************************/
printprolog (scale, llx, lly)
float scale;
int llx, lly;
{
printf ("%%%%Creator: poster - a tiling program by C.P. Lai\n\n");
X
printf ("\
/cropmark %% x y cropmark -\n\
{ %%def\n\
X /y exch def\n\
X /x exch def\n\
X gsave\n\
X 0 y rmoveto\n\
X 0 y 2 mul rlineto \n\
X gsave\n\
X 1 setgray 3 setlinewidth stroke %% paint background white to highlite mark\n\
X grestore\n\
X 0 setgray 0 setlinewidth stroke %% use thinnest line on device\n\
X grestore\n\
X x 0 rmoveto\n\
X x 2 mul 0 rlineto \n\
X gsave\n\
X 1 setgray 3 setlinewidth stroke %% paint background white to highlite mark\n\
X grestore\n\
X 0 setgray 0 setlinewidth stroke %% use thinnest line on device\n\
} bind def\n\n");
X
printf ("\
%% usage: row col tileprolog ps-code tilepilog\n\
%% these procedures output the tile specified by row & col\n\
/tileprolog\n\
{ %%def\n\
X gsave\n\
X /colcount exch def\n\
X /rowcount exch def\n\
X gsave\n\
X pagewidth colcount 1 sub mul neg\n\
X pageheight rowcount 1 sub mul neg\n\
X translate\n\
X sfactor dup scale\n\
X llx neg lly neg translate\n\
X tiledict begin\n\
} bind def\n\n");
X
printf("\
/tilepilog\n\
{ %%def\n\
X end %% of tiledict\n\
X grestore\n\
X %% output the crop marks\n\
X 0 0 moveto\n\
X -9 -9 cropmark\n\
X 0 pageheight moveto\n\
X -9 9 cropmark\n\
X pagewidth 0 moveto\n\
X 9 -9 cropmark\n\
X pagewidth pageheight moveto\n\
X 9 9 cropmark\n\n\
X 1 setgray\n\
X 18 -18 moveto\n\
X 0 9 rlineto\n\
X 72 0 rlineto\n\
X 0 -9 rlineto\n\
X closepath\n\
X fill\n\n\
X 0 setgray\n\
X 18 -18 moveto\n\
X (Grid \\( ) show\n\
X rowcount strg cvs show\n\
X ( , ) show\n\
X colcount strg cvs show\n\
X ( \\)) show\n\n\
X showpage\n\
X grestore\n\
} bind def\n\n");
X
printf("\
/sfactor %f def\n\
/llx %d def\n\
/lly %d def\n\
/leftmargin 36 def\n\
/botmargin 36 def\n\
/pagewidth %d def\n\
/pageheight %d def\n\n\
/strg 10 string def\n\
/tiledict 250 dict def\n\
tiledict begin\n\
/showpage {} def %% delay users showpage until cropmark is printed.\n\
end\n\
%% end of prolog\n\n", scale, llx, lly, (int) (PAGEW * 72), (int) (PAGEH * 72));
X
printf ("\
/Times-Roman findfont 9 scalefont setfont\n\
%% readjust the origin to coincides with the cropping mark\n\
leftmargin botmargin translate\n\n");
return;
}
X
/*****************************/
/* output one tile at a time */
/*****************************/
tile (pagename, row, col)
char *pagename;
int row, col;
{
printf ("%d %d tileprolog\n", row, col);
printf ("%% Start of included ps code\n%% vvvvvvvvvvvv\n");
printfile (pagename);
printf ("%% ^^^^^^^^^^^^\n%% End of included ps code\n");
printf ("tilepilog\n");
return;
}
X
/******************************/
/* copy the PS file to output */
/******************************/
printfile (filename)
char* filename;
{
char tmp_byte;
X
X if (freopen (filename, "r", stdin) == NULL) {
X fprintf (stderr, "fail to open file %s\n", filename);
X printf ("/systemdict /showpage get exec\n");
X exit (1);
X }
X while ((tmp_byte = getchar()) != EOF)
X putchar (tmp_byte);
X return;
}
X
/*********************************************/
/* extract BoundingBox info from the PS file */
/*********************************************/
getBoundingBox (filename, llxp, llyp, urxp, uryp)
char *filename;
int *llxp, *llyp, *urxp, *uryp;
{
char buf[BUFSIZE];
int not_found;
X
X /* initialize to 0 0 612 792 for defaults */
X *llxp = *llyp = 0;
X *urxp = 612; *uryp = 792;
X
X if (freopen (filename, "r", stdin) == NULL) {
X fprintf (stderr, "fail to open file %s\n", filename);
X exit (1);
X }
X not_found = TRUE;
X while (not_found && (gets(buf) != NULL)) {
X /* cut short if not found */
X if (strncmp (buf, "%%EndComments", 13) == 0) {
X not_found = FALSE;
X break;
X }
X if (sscanf (buf, "%%%%BoundingBox: %d %d %d %d", llxp, llyp, urxp, uryp) == 4)
X not_found = FALSE;
X }
X return;
}
SHAR_EOF
chmod 0644 poster.c ||
echo 'restore of poster.c failed'
Wc_c="`wc -c < 'poster.c'`"
test 7499 -eq "$Wc_c" ||
echo 'poster.c: original size 7499, current size' "$Wc_c"
fi
exit 0
--
|I| Ger Timmens |I| If you're not part of the solution, |I|
|M| 3D Computer Vision Group |M| you're part of the problem! |M|
|H| e-mail ger@cv.ruu.nl |H+-------------------------------------+H|
|O| or timmens@cs.unc.edu |O| Album by Joe Henderson (best tenor) |O|
Technical Details
Message-ID:
<1993Jan8.142107.26950@cv.ruu.nl>Path:
arc1-ca.pugleaf.net!sparky!uunet!mcsun!sun4nl!ruuinf!prisma.cv.ruu.nl!gerShow Full Headers
Complete Article Headers
Newsgroups: comp.lang.postscript Path: arc1-ca.pugleaf.net!sparky!uunet!mcsun!sun4nl!ruuinf!prisma.cv.ruu.nl!ger From: ger@cv.ruu.nl (Ger Timmens) Subject: poster (Scale 1page postscript files) Sender: usenet@cv.ruu.nl (Usenet Network) Message-ID: <1993Jan8.142107.26950@cv.ruu.nl> Date: Fri, 8 Jan 1993 14:21:07 GMT Nntp-Posting-Host: triton.cv.ruu.nl Organization: University of Utrecht, 3D Computer Vision Research Group Keywords: scaling/multiple pages Lines: 416