% Note and code from Steve Ness

% In other news, on the PostScript front (need to do something after
% working hours, after all...), I finally got a reasonable multi-page
% output routine "poster.ps" working last night;
% similar to the one in the Cookbook but somewhat more useful, IMHO.
% If you have a single page generated by code like
% 	/state save def
% 	... <PS code to draw a page of output> ...
% 	showpage
% 	state restore
% and you want to blow up the output image to a 24" x 31.5" poster on 9 separate
% sheets of 8.5" x 11" paper, you just change the above to
% 	/state save def
% 	% lib/poster.ps 11/11/93
% 	... <poster.ps code, cf. below> ...
% 	% end of lib/poster.ps
% 	/foo {
% 	... <PS code to draw a page of output> ...
% 	} bind def
% 	/foo load .25 inch .25 inch 8.25 inch 10.75 inch 24 inch 31.5 inch false poster
% 	state restore
% where you'll see the parameters explained in the source below.
% It is painful and kludgy to have to cut the edges off the resulting 8.5"x11"
% pages and tape them together, but it is a cheap way to print something BIG
% which looks fairly decent without going to a real printer.  Very useful
% for "Happy Birthday Anne" signs and the like...

% lib/poster.ps 11/11/93
% Multipage output: print a large poster.
% Cf. PostScript Language Tutorial and Cookbook, pp. 183-185.
% This routine is set up differently than the Cookbook example to facilitate
% printing single-sheet test versions of proc before blowing it up.

/inch { 72 mul } bind def

/posterdict 17 dict def		% px py pdx pdy newdx newdy urx ury llx lly
				% proc xscale yscale ncols nrows x y

% Routine poster takes as arguments a procedure proc
% and its bounding box parameters (llx, lly) and (urx, ury).
% It blows up the image to size (newdx, newdy) and prints it
% on separate 8 inch x 10.5 inch pages with .25 inch margins at each border.
% lflag is boolean: false for portrait, true for landscape;
% it should generally be false (even if proc prints in landscape)
% unless you want the poster output to be some multiple of 10.5" x 8".
% If the specified newdx is not a multiple of 8" (10.5" if landscape),
% the scaled image will not go all the way to the right of the poster.
% If the specified newdy is not a multiple of 10.5" (8" if landscape),
% the scaled image will not go all the way to the top of the poster.
% proc llx lly urx ury newdx newdy lflag poster -
/poster
{
	posterdict begin

	% Page format constants.
	/px  8.00 inch def			% page width
	/py 10.50 inch def			% page height
	/pdx  .25 inch def			% page horizontal offset
	/pdy  .25 inch def			% page vertical offset

	% Landscape format if lflag.
	{
		/px 10.50 inch def		% page width
		/py  8.00 inch def		% page height
		90 rotate
		0 -8.5 inch translate
	} if

	/newdy exch def
	/newdx exch def
	/ury exch def
	/urx exch def
	/lly exch def
	/llx exch def
	/proc exch def

	/xscale newdx urx llx sub div def	% horizontal scale factor
	/yscale newdy ury lly sub div def	% vertical scale factor
	/ncols newdx px div ceiling def		% horizontal page count
	/nrows newdy py div ceiling def		% vertical page count

	0 1 ncols 1 sub {			% for each column of output pages
		px mul /x exch def
		0 1 nrows 1 sub {		% for each row of output pages
			py mul /y exch def
			gsave

			% Define clipping box and stroke it.
			newpath
			pdx pdy moveto
			px 0 rlineto
			0 py rlineto
			px neg 0 rlineto
			closepath clip stroke

			% Translate appropriately.
			pdx pdy translate	% adjust for page margins
			x neg y neg translate	% move to desired page position
			xscale yscale scale	% scale image to desired size
			llx neg lly neg translate	% ll to (0,0)

			% Print a page.
			% posterdict would overflow if proc defines any
			% variables, hence it is popped and repushed here.
			/proc load		% proc to stack
			end			% remove posterdict for proc
			exec			% execute proc
			posterdict begin	% restore posterdict
			showpage		% print one page

			grestore
		} for				% for each row
	} for					% for each column
	end					% end of posterdict
} bind def

% Example: suppose
%	foo showpage
% draws the desired image on a single 8.5" x 11" page,
% not writing in a .25" margin at each border.
% To print at scale 2::1 on four pages, replace the above with:
%	/foo load .25 inch .25 inch 8.25 inch 10.75 inch 16 inch 21 inch false poster

% end of lib/poster.ps
