123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- %
- % Procedures that let you print any number of pages on each sheet of paper. It's
- % far from perfect and won't handle everything (eg. it's not recursive), but should
- % be good enough for now. Assumes the default page coordinate system has been set
- % up before setupforms is called. lastpage makes certain the last page is printed,
- % and should be called immediately after the %%Trailer comment.
- %
- % Three lines of code needed for page image clipping have been commented out for
- % now. It works, but can really slow things down on some versions of PostScript.
- % Uncomment them if you want to clip pages.
- %
- /setupforms {
- /formsperpage exch def
- /currentform 0 def
- /slop 5 def
- /min {2 copy gt {exch} if pop} def
- %
- % Save the current environment so the real showpage can be restored when we're all
- % done. Occasionally helps when a banner page is included with the job.
- %
- /saveobj save def
- %
- % Number of rows and columns we'll need - may exchange them later.
- %
- /columns formsperpage sqrt ceiling cvi def
- /rows formsperpage columns div ceiling cvi def
- %
- % Slop leaves a little room around the edge so page images can be outlined and have
- % the borders show up. Distance is in default coordinates, so we need to figure out
- % how it maps into user coordinates.
- %
- 6 array defaultmatrix
- 6 array currentmatrix
- 6 array invertmatrix
- 6 array concatmatrix
- /tempmatrix exch def
- 0 slop tempmatrix dtransform dup mul exch dup mul add sqrt
- /slop exch def
- %
- % Determine how big the image area is, using the clipping path bounding box minus
- % a little and leave the coordinates of the lower left corner of the clipping path
- % on the stack. Also temporarily set the size of each page (ie. formheight and
- % formwidth) from the clipping path - just in case old software uses this stuff.
- % Only works for coordinate systems that have been rotated by a multiple of 90
- % degrees.
- %
- newpath clippath pathbbox
- 2 index sub dup /formheight exch def slop 2 mul sub /pageheight exch def
- 2 index sub dup /formwidth exch def slop 2 mul sub /pagewidth exch def
- %
- % New translators all store the size of each page in default coordinates in the
- % pagebbox array and it can be different than the size determined by the clipping
- % path. If we can find pagebbox use it to set the real dimensions of each page.
- % Leaves the coordinates of the lower left corner on the stack, (either from
- % pagebbox or clippath) so four numbers are there when we're done.
- %
- userdict /gotpagebbox known userdict /pagebbox known and {
- newpath
- pagebbox 0 get pagebbox 1 get tempmatrix transform moveto
- pagebbox 0 get pagebbox 3 get tempmatrix transform lineto
- pagebbox 2 get pagebbox 3 get tempmatrix transform lineto
- pagebbox 2 get pagebbox 1 get tempmatrix transform lineto
- closepath pathbbox
- 2 index sub /formheight exch def
- 2 index sub /formwidth exch def
- } {2 copy} ifelse
- %
- % Top two numbers are the displacement from the job's origin to the lower left
- % corner of each page image when we finish setting up the new coordinate system.
- %
- /ycorner exch def
- /xcorner exch def
- %
- % The two numbers left on the stack are the coordinates of the lower left corner
- % of the clipping path. Go there and then up a bit so page images can be outlined.
- %
- translate
- slop slop translate
- %
- % If the page is wider than high we may be able to do better if we exchange rows
- % and columns. Won't make a difference in the current orientation or if rows and
- % columns are the same.
- %
- pagewidth pageheight gt {
- rows columns /rows exch def /columns exch def
- } if
- %
- % Find the orientation and scaling that makes things as large as possible. More
- % than what's really needed. First calculation essentially finds the minimum of
- % 1/rows and 1/columns.
- %
- pagewidth formwidth columns mul div pageheight formheight rows mul div min
- pageheight formwidth columns mul div pagewidth formheight rows mul div min
- 2 copy lt {
- rotation 1 eq {
- landscape {
- 0 pageheight translate
- -90 rotate
- }{
- pagewidth 0 translate
- 90 rotate
- } ifelse
- }{
- landscape {
- pagewidth 0 translate
- 90 rotate
- }{
- 0 pageheight translate
- -90 rotate
- } ifelse
- } ifelse
- pagewidth pageheight /pagewidth exch def /pageheight exch def
- exch
- } if
- %
- % Second number from the top is the best choice. Scale so everything will fit on
- % the current page, go back to the original origin, and then get ready for the
- % first page - which goes in the upper left corner.
- %
- pop dup dup scale
- xcorner neg ycorner neg translate
- 0 rows 1 sub formheight mul translate
- %
- % Try to center everything on the page - scaling we used is on top of the stack.
- %
- dup pagewidth exch div formwidth columns mul sub 2 div
- exch pageheight exch div formheight rows mul sub 2 div translate
- %
- % Redefine showpage.
- %
- /!PreForms~showpage~ /showpage load def % save current showpage
- /showpage {
- saveobj restore
- % initclip
- formsperpage 1 gt {
- gsave .1 setlinewidth outlineform stroke grestore
- } if
- formwidth 0 translate
- /currentform currentform 1 add def
- currentform columns mod 0 eq {
- columns formwidth mul neg formheight neg translate
- } if
- currentform formsperpage mod 0 eq {
- gsave !PreForms~showpage~ grestore
- currentform columns mod formwidth mul neg
- formsperpage columns idiv formheight mul translate
- /currentform 0 def
- } if
- % outlineform clip newpath
- /saveobj save def
- } bind def
- /outlineform {
- newpath
- xcorner ycorner moveto
- formwidth 0 rlineto
- 0 formheight rlineto
- formwidth neg 0 rlineto
- closepath
- } bind def
- /lastpage {
- formsperpage 1 gt {
- currentform 0 ne {
- /saveobj save def
- 0 1 formsperpage currentform sub formsperpage mod {
- pop showpage
- } for
- saveobj restore
- } if
- saveobj restore
- saveobj restore
- } if
- } def
- %
- % Clip the first page image and save the environment we just set up, including
- % the redefined showpage.
- %
- % outlineform clip
- newpath
- /saveobj save def
- } def
|