|
|
1.1 ! root 1: % ! 2: % Procedures that let you print any number of pages on each sheet of paper. It's ! 3: % far from perfect and won't handle everything (eg. it's not recursive), but should ! 4: % be good enough for now. Assumes the default page coordinate system has been set ! 5: % up before setupforms is called. lastpage makes certain the last page is printed, ! 6: % and should be called immediately after the %%Trailer comment. ! 7: % ! 8: % Three lines of code needed for page image clipping have been commented out for ! 9: % now. It works, but can really slow things down on some versions of PostScript. ! 10: % Uncomment them if you want to clip pages. ! 11: % ! 12: ! 13: /setupforms { ! 14: /formsperpage exch def ! 15: ! 16: /currentform 0 def ! 17: /slop 5 def ! 18: /min {2 copy gt {exch} if pop} def ! 19: ! 20: % ! 21: % Save the current environment so the real showpage can be restored when we're all ! 22: % done. Occasionally helps when a banner page is included with the job. ! 23: % ! 24: ! 25: /saveobj save def ! 26: ! 27: % ! 28: % Number of rows and columns we'll need - may exchange them later. ! 29: % ! 30: ! 31: /columns formsperpage sqrt ceiling cvi def ! 32: /rows formsperpage columns div ceiling cvi def ! 33: ! 34: % ! 35: % Slop leaves a little room around the edge so page images can be outlined and have ! 36: % the borders show up. Distance is in default coordinates, so we need to figure out ! 37: % how it maps into user coordinates. ! 38: % ! 39: ! 40: 6 array defaultmatrix ! 41: 6 array currentmatrix ! 42: 6 array invertmatrix ! 43: 6 array concatmatrix ! 44: /tempmatrix exch def ! 45: ! 46: 0 slop tempmatrix dtransform dup mul exch dup mul add sqrt ! 47: /slop exch def ! 48: ! 49: % ! 50: % Determine how big the image area is, using the clipping path bounding box minus ! 51: % a little and leave the coordinates of the lower left corner of the clipping path ! 52: % on the stack. Also temporarily set the size of each page (ie. formheight and ! 53: % formwidth) from the clipping path - just in case old software uses this stuff. ! 54: % Only works for coordinate systems that have been rotated by a multiple of 90 ! 55: % degrees. ! 56: % ! 57: ! 58: newpath clippath pathbbox ! 59: 2 index sub dup /formheight exch def slop 2 mul sub /pageheight exch def ! 60: 2 index sub dup /formwidth exch def slop 2 mul sub /pagewidth exch def ! 61: ! 62: % ! 63: % New translators all store the size of each page in default coordinates in the ! 64: % pagebbox array and it can be different than the size determined by the clipping ! 65: % path. If we can find pagebbox use it to set the real dimensions of each page. ! 66: % Leaves the coordinates of the lower left corner on the stack, (either from ! 67: % pagebbox or clippath) so four numbers are there when we're done. ! 68: % ! 69: ! 70: userdict /gotpagebbox known userdict /pagebbox known and { ! 71: newpath ! 72: pagebbox 0 get pagebbox 1 get tempmatrix transform moveto ! 73: pagebbox 0 get pagebbox 3 get tempmatrix transform lineto ! 74: pagebbox 2 get pagebbox 3 get tempmatrix transform lineto ! 75: pagebbox 2 get pagebbox 1 get tempmatrix transform lineto ! 76: closepath pathbbox ! 77: 2 index sub /formheight exch def ! 78: 2 index sub /formwidth exch def ! 79: } {2 copy} ifelse ! 80: ! 81: % ! 82: % Top two numbers are the displacement from the job's origin to the lower left ! 83: % corner of each page image when we finish setting up the new coordinate system. ! 84: % ! 85: ! 86: /ycorner exch def ! 87: /xcorner exch def ! 88: ! 89: % ! 90: % The two numbers left on the stack are the coordinates of the lower left corner ! 91: % of the clipping path. Go there and then up a bit so page images can be outlined. ! 92: % ! 93: ! 94: translate ! 95: slop slop translate ! 96: ! 97: % ! 98: % If the page is wider than high we may be able to do better if we exchange rows ! 99: % and columns. Won't make a difference in the current orientation or if rows and ! 100: % columns are the same. ! 101: % ! 102: ! 103: pagewidth pageheight gt { ! 104: rows columns /rows exch def /columns exch def ! 105: } if ! 106: ! 107: % ! 108: % Find the orientation and scaling that makes things as large as possible. More ! 109: % than what's really needed. First calculation essentially finds the minimum of ! 110: % 1/rows and 1/columns. ! 111: % ! 112: ! 113: pagewidth formwidth columns mul div pageheight formheight rows mul div min ! 114: pageheight formwidth columns mul div pagewidth formheight rows mul div min ! 115: ! 116: 2 copy lt { ! 117: rotation 1 eq { ! 118: landscape { ! 119: 0 pageheight translate ! 120: -90 rotate ! 121: }{ ! 122: pagewidth 0 translate ! 123: 90 rotate ! 124: } ifelse ! 125: }{ ! 126: landscape { ! 127: pagewidth 0 translate ! 128: 90 rotate ! 129: }{ ! 130: 0 pageheight translate ! 131: -90 rotate ! 132: } ifelse ! 133: } ifelse ! 134: pagewidth pageheight /pagewidth exch def /pageheight exch def ! 135: exch ! 136: } if ! 137: ! 138: % ! 139: % Second number from the top is the best choice. Scale so everything will fit on ! 140: % the current page, go back to the original origin, and then get ready for the ! 141: % first page - which goes in the upper left corner. ! 142: % ! 143: ! 144: pop dup dup scale ! 145: xcorner neg ycorner neg translate ! 146: 0 rows 1 sub formheight mul translate ! 147: ! 148: % ! 149: % Try to center everything on the page - scaling we used is on top of the stack. ! 150: % ! 151: ! 152: dup pagewidth exch div formwidth columns mul sub 2 div ! 153: exch pageheight exch div formheight rows mul sub 2 div translate ! 154: ! 155: % ! 156: % Redefine showpage. ! 157: % ! 158: ! 159: /showpage { ! 160: saveobj restore ! 161: % initclip ! 162: formsperpage 1 gt { ! 163: gsave .1 setlinewidth outlineform stroke grestore ! 164: } if ! 165: formwidth 0 translate ! 166: /currentform currentform 1 add def ! 167: currentform columns mod 0 eq { ! 168: columns formwidth mul neg formheight neg translate ! 169: } if ! 170: currentform formsperpage mod 0 eq { ! 171: gsave showpage grestore ! 172: currentform columns mod formwidth mul neg ! 173: formsperpage columns idiv formheight mul translate ! 174: /currentform 0 def ! 175: } if ! 176: % outlineform clip newpath ! 177: /saveobj save def ! 178: } bind def ! 179: ! 180: /outlineform { ! 181: newpath ! 182: xcorner ycorner moveto ! 183: formwidth 0 rlineto ! 184: 0 formheight rlineto ! 185: formwidth neg 0 rlineto ! 186: closepath ! 187: } bind def ! 188: ! 189: /lastpage { ! 190: formsperpage 1 gt { ! 191: currentform 0 ne { ! 192: /saveobj save def ! 193: 0 1 formsperpage currentform sub formsperpage mod { ! 194: pop showpage ! 195: } for ! 196: saveobj restore ! 197: } if ! 198: saveobj restore ! 199: saveobj restore ! 200: } if ! 201: } def ! 202: ! 203: % ! 204: % Clip the first page image and save the environment we just set up, including ! 205: % the redefined showpage. ! 206: % ! 207: ! 208: % outlineform clip ! 209: newpath ! 210: /saveobj save def ! 211: } def
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.